1、装饰器简介
Python 的装饰器是一种非常有用的功能,可以使用户在不修改原有函数或方法定义的情况下,给这些函数或方法增加额外的功能。装饰器本质上是一个函数,它接受一个函数作为参数并返回一个新的函数。装饰器可以使代码更简洁。
import time
def log_calls(func):
def wrapper(*args,**kwargs):
now = time.time()
print("Calling {0} with {1} and {2}".format(func.__name__,args,kwargs))
return_value = func(*args, **kwargs)
print("Executed {0} in {1}ms".format(func.__name__,time.time()-now))
return return_value
return wrapper
def test1(a,b,c):
print("test1 called")
def test2(a,b):
print("test2 called")
def test3(a,b):
print("test3 called")
time.sleep(1)
test1 = log_calls(test1)
test2 = log_calls(test2)
test3 = log_calls(test3)
>>> test1(1,2,3)
Calling test1 with (1, 2, 3) and {}
test1 called
Executed test1 in 0.00017595291137695312ms
>>> test2(4,b=5)
Calling test2 with (4,) and {'b': 5}
test2 called
Executed test2 in 9.918212890625e-05ms
>>> test3(6,7)
Calling test3 with (6, 7) and {}
test3 called
Executed test3 in 1.0013248920440674ms
通过装饰器实现上述代码,
import time
def log_calls(func):
def wrapper(*args,**kwargs):
now = time.time()
print("Calling {0} with {1} and {2}".format(func.__name__,args,kwargs))
return_value = func(*args, **kwargs)
print("Executed {0} in {1}ms".format(func.__name__,time.time()-now))
return return_value
return wrapper
@log_calls
def test1(a,b,c):
print("test1 called")
@log_calls
def test2(a,b):
print("test2 called")
@log_calls
def test3(a,b):
print("test3 called")
time.sleep(1)
>>> test1(1,2,3)
Calling test1 with (1, 2, 3) and {}
test1 called
Executed test1 in 0.00017595291137695312ms
>>> test2(4,b=5)
Calling test2 with (4,) and {'b': 5}
test2 called
Executed test2 in 9.918212890625e-05ms
>>> test3(6,7)
Calling test3 with (6, 7) and {}
test3 called
Executed test3 in 1.0013248920440674ms
@log_calls这样的写法就是使用装饰器
2、通过装饰器创建property
使用@property
可以创建出既简洁又易于使用的类接口,同时还能保持对数据的严格控制。通过使用property
装饰器,可以创建出既安全又易于使用的类接口,同时还能保持代码的简洁性和灵活性。
class Circle: def __init__(self, radius): self._radius = radius @property def radius(self): """获取圆的半径""" return self._radius @radius.setter def radius(self, value): """设置圆的半径,并进行简单的校验""" if value < 0: raise ValueError("Radius cannot be negative") self._radius = value @property def diameter(self): """计算并返回圆的直径""" return self._radius * 2 # 使用Circle类 circle = Circle(5) print(circle.radius) # 获取半径,输出: 5 print(circle.diameter) # 获取直径,输出: 10 circle.radius = 10 # 设置半径 print(circle.radius) # 再次获取半径,输出: 10 print(circle.diameter) # 再次获取直径,输出: 20 # 尝试设置半径为负数,将抛出ValueError # circle.radius = -2