python 類demo(2)__metaclass__批量化新增屬性
阿新 • • 發佈:2019-02-11
__metaclass__批量化新增屬性
>>> def ma(cls): #注意cls 不然報錯。沒有ma屬性 print 'method a' >>> def mb(cls): #注意cls 不然報錯。沒有mb屬性 print 'method b' >>> method_dict = {'ma':ma,'mb':mb} >>> class Dy(type): def __new__(cls,name, bases, dct): if name[:3] == 'Abc': dct.update(method_dict) return type.__new__(cls, name, bases, dct) def __init__(cls, name, bases, dct): super(Dy,cls).__init__(name,bases,dct) >>> class AbcTest(object): __metaclass__ = Dy def mc(self,x): print x *3 >>> class NotAbc(object): __metaclass__ = Dy def md(self,x): print x * 3 >>> def main(): a = AbcTest() a.mc(3) #例項 a 呼叫 AbcTest 的 mc() #9 a.ma() #因為DY類中增加了 ma,mb 屬性,所以可以呼叫 ma,mb 函式 #method a print dir(a) #返回例項 a 擁有的屬性 b = NotAbc() print dir(b) #例項 b 沒有增加 ma,mb 屬性 >>> main() 9 method a ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__','__metaclass__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'ma', 'mb', 'mc'] ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__','__metaclass__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'md']
通過__metaclass__ = 呼叫類 動態的給類 AbcTest() 新增屬性,(判斷類的名稱)
#!/usr/bin/python #coding :utf-8 from types import FunctionType def login_required(func): print 'login check logic here' return func class LoginDecorator(type): def __new__(cls, name, bases, dct): for name, value in dct.iteritems(): if name notin ('__metaclass__','__init__', '__module__')and\ type(value) == FunctionType: value = login_required(value) dct[name] = value return type.__new__(cls, name, bases, dct) class Operation(object): __metaclass__ = LoginDecorator def delete(self, x): print 'deleted %s' % str(x) def main(): op = Operation() op.delete('test') if __name__ == '__main__': main()
2. 批量的對某些方法使用decorator,而不需要每次都在方法的上面加入@decorator_func 這個其實有應用場景的,就是比如我們cgi程式裡面,很多需要驗證登入或者是否有許可權的,只有驗證通過之後才 可以操作。那麼如果你有很多個操作都需要這樣做,我們一般情況下可以手動在每個方法的前頭用@login_required 類似這樣的方式。那如果學習了metaclass的使用的話,這次你也可以這樣做: 這樣子你就可以不用在delete函式上面寫@login_required, 也能達到decorat的效果了。不過可讀性就差點了。