1.函数装饰器
import time
def fucker0(m):
print(m)
def fucker(fuc):
def fucker2(*args, **kwargs):
st_time=time.time()
s=fuc(*args, **kwargs)#注意参数传递
ed_time=time.time()
print('程序运行时间为%s' %(ed_time-st_time))
return s
return fucker2
return fucker
@fucker0('bitch') #有参装饰器
def shit(a, b=None):
if b is None:
b = {}
b.update({"name": 23, 'age': 46})
a = a**2
time.sleep(1)
print('程序运行结果是%s,%s' % (a, b))
return a, b
q=shit(3, b={7:8})
print(q)
#result
bitch
程序运行结果是9,{7: 8, 'name': 23, 'age': 46}
程序运行时间为1.003929615020752
(9, {7: 8, 'name': 23, 'age': 46})
装饰器只运行一次,相当于永久改变了函数名指向的代码,因此函数嵌套是必要的
2.类的装饰器
装饰器本质上在装饰对象,python中一切皆对象.
下例利用装饰器来为类添加属性
@staticmethod
def adding(self): # 把此函数加入类
print('我是新增加的属性', self.b)
def Dec0(**kwargs):
print('hahaha')
def Dec(obj):
for i in kwargs:
# obj.i = kwargs[i] # 此种方法不行,会把i当成字符串(key)
# obj.__dict__[i] = kwargs[i] #此种方法也不支持
setattr(obj, i, kwargs[i])
return obj
return Dec
@Dec0(x=3, a4=5, adding=adding) # 当然也可添加一个函数属性!!!
class Test:
name= 'sabi' # 字典的键相当于一个变量
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
t = Test(1,2,3)
t2 = Test(4,5,6)
print(t.a)
print(t.__dict__)
print(Test.x)
Test.adding(t2)
t.adding(t)
#result
hahaha
1
{'a': 1, 'b': 2, 'c': 3}
3
我是新增加的属性 5
我是新增加的属性 2
2.1关于类装饰器的一些说明
The motivating use-case was to make certain constructs more easily expressed and less reliant on implementation details of the CPython interpreter. While it is possible to express class decorator-like functionality using metaclasses, the results are generally unpleasant and the implementation highly fragile [3]. In addition, metaclasses are inherited, whereas class decorators are not, making metaclasses unsuitable for some, single class-specific uses of class decorators. The fact that large-scale Python projects like Zope were going through these wild contortions to achieve something like class decorators won over the BDFL
令人鼓舞的用案例例是使某些构造更容易表达,并且更少依赖于CPython解释器的实现细节。 虽然可以使用元类表达类装饰器类功能,但结果通常令人不愉快并且实现非常脆弱。 此外,元类是继承的,而类装饰器则不是,使得元类不适合类装饰器的某些特定于类的特定用途。 事实上像Zope这样的大型Python项目经历了这些疯狂的扭曲,以实现类似装饰器的东西赢得了BDFL