1. 程式人生 > >python 類demo(2)__metaclass__批量化新增屬性

python 類demo(2)__metaclass__批量化新增屬性

__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的效果了。不過可讀性就差點了。