在class语句的末尾,类装饰器把类名重绑定的一个可调用对象;
在class语句的末尾,元类把类对象的创建指定到type的子类;
类装饰器可以管理类对象和类实例;
元类比较适合管理类对象,用于管理类实例会比较复杂。
通过类装饰器也可以扩展类方法。
描述
装饰器通过返回装饰类保留原类类型来管理类。
对装饰类添加方法来自动扩展全部被装饰的类。
示例
# obj 类似 self,类的方法第1个入参为self
>>> def triple(obj):
return obj.value*3
>>> def joinf(obj,value):
return value+'装饰器自动扩展'
>>> def MyDecorator(aCls):
# 添加装饰类的方法
aCls.triple=triple
aCls.joinf=joinf
# 返回装饰类保留最初的类类型
return aCls
# 通过装饰器自动添加方法
>>> @MyDecorator
class ClsA():
def __init__(self,value):
self.value=value
def double(self):
return self.value*2
>>> @MyDecorator
class ClsB():
value=5
>>> ca1=ClsA(6)
>>> ca1.double()
12
>>> ca1.triple()
18
>>> ca1.joinf('ca1')
'ca1元类自动扩展'
>>> cb1=ClsB()
>>> cb1.triple()
15
>>> cb1.joinf('cb1')
'cb1元类自动扩展'
类装饰器可以管理类和实例。
元类可以管理类和实例,比较适合管理类,管理实例需比较多的额外代码。
描述
装饰器管理类实例需要返回包装器,通过getattr()拦截装饰类的实例属性。
示例
>>> def TracerDeco(aCls):
# 装饰器管理实例需返回包装器
class Wrapper:
def __init__(self,*args,**kargs):
self.wrapped=aCls(*args,**kargs)
# 通过__getattr__()拦截实例属性
def __getattr__(self,attrname):
print('装饰器getattr:',attrname)
return getattr(self.wrapped,attrname)
return Wrapper
>>> @TracerDeco
class Staff:
def __init__(self,name,days,rate):
self.name=name
self.days=days
self.rate=rate
def pay(self):
return self.days*self.rate
>>> s1=Staff('梯阅线条',22,3000)
>>> s1.name,s1.pay()
装饰器getattr: name
装饰器getattr: pay
('梯阅线条', 66000)
描述
元类管理类实例,需要先用type()创建类对象,再通过包装器管理类实例,拦截客户类的实例属性。
示例
>>> def TracerMeta(classname,supers,classdict):
# 元类管理实例先用type()创建类对象
aClass=type(classname,supers,classdict)
# 再用包装器管理类实例
class Wrapper:
def __init__(self,*args,**kargs):
self.wrapped=aClass(*args,**kargs)
def __getattr__(self,attrname):
print('元类getattr:',attrname)
return getattr(self.wrapped,attrname)
return Wrapper# 返回包装器
>>> class Staff(metaclass=TracerMeta):
def __init__(self,name,days,rate):
self.name=name
self.days=days
self.rate=rate
def pay(self):
return self.days*self.rate
>>> s1=Staff('梯阅线条',22,3000)
>>> s1.name,s1.pay()
元类getattr: name
元类getattr: pay
('梯阅线条', 66000)