国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Python屬性、方法和類管理系列之----元類

2019-11-14 17:02:55
字體:
來源:轉載
供稿:網友

元類的介紹

請看位于下面網址的一篇文章,寫的相當好。
http://blog.jobbole.com/21351/

實例補充

class Meta(type):    def __new__(meta, cls, parent, attr_dict):        res = super(Meta, meta).__new__(meta,cls, parent, attr_dict)        PRint('meta new stage, %s is %s, %s is %s' % (meta, type(meta), cls, type(cls)))         return res    def __init__(self,cls, parent, attr_dict):        super(Meta, self).__init__(cls,parent, attr_dict)        print('meta init stage, %s is %s, %s is %s' % (self, type(self), cls, type(cls)))    def __call__(self, *args, **kargs):        print('meta call stage, %s is %s' % (self, type(self)))        return super(Meta, self).__call__(*args, **kargs)def decorate(cls):    print('decorate cls, %s is %s' % (cls, type(cls)))    return cls@decorateclass A(metaclass=Meta):    def __new__(cls):        res = super(A, cls).__new__(cls)        print('A new stage, %s is %s' % (cls, type(cls)))        return res    def __init__(self):        super(A, self).__init__()        print('A init stage, %s is %s' % (self, type(self)))    def test(self):        passa=A()print(a)

運行結果如下:

meta new stage, <class '__main__.Meta'> is <class 'type'>, A is <class 'str'>meta init stage, <class '__main__.A'> is <class '__main__.Meta'>, A is <class 'str'>decorate cls, <class '__main__.A'> is <class '__main__.Meta'>meta call stage, <class '__main__.A'> is <class '__main__.Meta'>A new stage, <class '__main__.A'> is <class '__main__.Meta'>A init stage, <__main__.A object at 0x00000000022A74E0> is <class '__main__.A'><__main__.A object at 0x00000000022A74E0>

說明:
當我們自己創建一個類時,其實Python內部的運作機制如下:

  1. 看這個類中是否有設置元類,如果有,調用該元類進行初始化,如果沒有,調用type進行初始化。
  2. 無論是我們自己定義的元類還是type,都有一個__new__方法,用來生成元類, 都有一個__init__用來初始化類。
  3. 查看是否有類的裝飾器,如果有的話,調用之。
    其實,元類的__new____init__幾乎什么都不做。
    當我們創建一個類的實例時,其實Python內部的運作機制如下:
  4. 調用元類的__call__方法,該方法會做兩件事情:
  • 調用類自身的__new__方法用來創建類(如果有的話),如果我們沒有顯示的定義它,那么會調用從object繼承過來的__new__方法。
  • 調用類自身的__init__方法(如果有的話)來初始化得到實例,如果我們沒有顯示的定義它,那么會調用從object繼承過來的__init__方法。
    其實,object的__init__幾乎什么都不做。

應用實例

由于我們經常在寫類的內置攔截器方法時,少寫下劃線,或者出現拼寫錯誤,從而怎么調試都不能發現問題所在,在浪費了很多時間以后才發現時犯的是多么低級的錯誤。
下面我寫了這個元類來進行檢查。

class AttrCheckMeta(type):    def __new__(meta, cls, parent, attr_dict):        import types        attrs_checking_list=['__init__', '__del__', '__call__', '__str__', '__repr__',                     '__getattr__', '__setattr__', '__delattr__', '__getattribute__',                    '__getitem__', '__setitem__', '__delitem__', '__iter__', '__next__',                    '__contains__', '__get__', '__set__', '__delete__', '__lt__',                     '__le__', '__gt__', '__ge__', '__eq__', '__add__', '__iadd__',                     '__radd__', '__sub__', '__isub__', '__rsub__', '__mul__', '__imul__',                    '__neg__', '__pos__', '__abs__', '__floordiv__', '__ifloordiv__',                     '__truediv__', '__itruediv__', '__mod__', '__imod__', '__imod__',                     '__pow__', '__ipow__', '__concat__', '__iconcat__', '__and__',                     '__iand__', '__or__', '__ior__', '__xor__', '__ixor__', '__inv__',                     '__invert__ ', '__lshift__', '__ilshift__', '__rshift__', '__irshift__ ',                    '__bool__', '__len__', '__nonzero__', '__enter__', '__exit__',                    '__new__', '__index__', '__oct__', '__hex__']        for attr,value in attr_dict.items():            #處理方法名前后都包含__,但是名字寫錯的情況。            if attr[:2]=='__' and attr[-2:]=='__' and isinstance(value, types.FunctionType):                if attr not in attrs_checking_list:                    print('found problem function: %s' % attr)            #處理漏寫后面__的情況,此時Python會把這個方法嗎當成是需要擴張的方法。            elif attr.startswith('_'+cls+'__') and isinstance(value, types.FunctionType):                print('maybe has problem: %s' % attr)        return super(AttrCheckMeta, meta).__new__(meta,cls, parent, attr_dict)    def __init__(self,cls, parent, attr_dict):        super(AttrCheckMeta, self).__init__(cls,parent, attr_dict)    def __call__(self, *args, **kargs):        return super(AttrCheckMeta, self).__call__(*args, **kargs)class A(metaclass=AttrCheckMeta):    def __new__(cls):        return super(A, cls).__new__(cls)    def __add(self, va, val):        pass    def __innit__(self):        super(A, self).__init__()a=A()

故意寫了兩個錯誤在類A中,運行結果如下:

found problem function name: __innit__maybe has problem: _A__add

當然,這個可以用裝飾器來完成同樣的任務,而且裝飾器似乎更加直白、容易理解。
代碼如下:

def check_ol(cls):    '''the overloading function name is easily to have spelling mistake.    It will be very hard to find the related mistakes, so i use this automethod to check    It will print the possible mistakes once found, will do nothing if passed'''    import types    attrs_checking_list=['__init__', '__del__', '__call__', '__str__', '__repr__',                 '__getattr__', '__setattr__', '__delattr__', '__getattribute__',                '__getitem__', '__setitem__', '__delitem__', '__iter__', '__next__',                '__contains__', '__get__', '__set__', '__delete__', '__lt__',                 '__le__', '__gt__', '__ge__', '__eq__', '__add__', '__iadd__',                 '__radd__', '__sub__', '__isub__', '__rsub__', '__mul__', '__imul__',                '__neg__', '__pos__', '__abs__', '__floordiv__', '__ifloordiv__',                 '__truediv__', '__itruediv__', '__mod__', '__imod__', '__imod__',                 '__pow__', '__ipow__', '__concat__', '__iconcat__', '__and__',                 '__iand__', '__or__', '__ior__', '__xor__', '__ixor__', '__inv__',                 '__invert__ ', '__lshift__', '__ilshift__', '__rshift__', '__irshift__ ',                '__bool__', '__len__', '__nonzero__', '__enter__', '__exit__',                '__new__', '__index__', '__oct__', '__hex__']    for attr,value in cls.__dict__.items():        #處理方法名前后都包含__,但是名字寫錯的情況。        if attr[:2]=='__' and attr[-2:]=='__' and isinstance(value, types.FunctionType):            if attr not in attrs_checking_list:                print('found problem function name: %s' % attr)        #處理漏寫后面__的情況,此時Python會把這個方法嗎當成是需要擴張的方法。        elif attr.startswith('_'+cls.__name__+'__') and isinstance(value, types.FunctionType):            print('maybe has problem: %s' % attr)    return cls

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 九江市| 高邑县| 高安市| 吉林省| 桐柏县| 股票| 镇安县| 丹阳市| 宿松县| 镇宁| 水富县| 滦平县| 漳平市| 开远市| 繁昌县| 牙克石市| 莱州市| 五寨县| 怀集县| 平定县| 柳江县| 沙雅县| 当涂县| 滕州市| 莒南县| 盐池县| 阿城市| 阿合奇县| 武宁县| 津南区| 威信县| 镇江市| 肥乡县| 大厂| 古丈县| 绥棱县| 尤溪县| 来宾市| 兴业县| 万源市| 沅陵县|