@Kaniz開羅
一個元類是一個類的類。一個類定義了類的實例(對象)的行為,一個元類定義了一個類的行為。一個類是一個元類的一個實例。
雖然在Python中你可以使用任意的元類(如可調用的Jerub顯示),更好的方法是一個實際的類本身。類型通常是Python中的元類。類型本身就是一個類,它是它自己的類型。你不能重新創建類似於Python類型純粹,但Python欺騙。創建自己的Python中的元類你真的隻是想子類類型。
一個元類是最常用的類工廠。當你創建一個對象通過調用類,Python創建一個新類(它執行類的語句時)通過調用元類。結合正常__init__和__new__方法,因此元類允許你做額外的事情當創建一個類,如注冊新類和一些注冊表或完全用別的東西代替類。
執行類聲明時,Python首先執行的主體類聲明作為一個正常的代碼塊。由此產生的名稱空間(dict)類的屬性。元類是由觀察的baseclass類(元類都繼承了),在__metaclass__類的屬性(如果有的話)或__metaclass__全局變量。然後使用元類的名稱、基地和屬性的類來實例化它。
然而,元類定義類型類的,不僅僅是一個工廠,所以你可以做得更多。例如,您可以定義正常的元類上的方法。這些metaclass-methods是類方法一樣,他們可以被稱為類沒有實例,但他們也不像類方法,他們不能被稱為類的一個實例。type.__subclasses__()方法的一個例子在元類類型。您還可以定義正常的‘魔法’方法,像__add__ __iter__ __getattr__,實現或改變行為的類。這是一個聚合的例子的片段:
def make_hook (f):“”“裝飾將“foo”方法變成__foo__”“f。is_hook = 1返回f類MyType(類型):def __new__(製程、名稱、基地、attrs):如果name.startswith(“沒有”):返回沒有#超過屬性,看他們是否應該重新命名。newattrs = {} attrname, attrvalue attrs.iteritems():如果getattr (attrvalue is_hook, 0): newattrs[的__ % s__ % attrname] = attrvalue: newattrs [attrname] = attrvalue返回超級(MyType,製程)。__new__(製程、名稱、基地、newattrs) def __init__(自我、名稱、基地、attrs):超級(MyType,自我)。__init__(名稱、基地attrs) # classregistry。注冊(自我,self.interfaces)打印“現在注冊類% s。”% self def __add__(self, other): class AutoClass(self, other): pass return AutoClass # Alternatively, to autogenerate the classname as well as the class: # return type(self.__name__ + other.__name__, (self, other), {}) def unregister(self): # classregistry.unregister(self) print "Would unregister class %s now." % self class MyObject: __metaclass__ = MyType class NoneSample(MyObject): pass # Will print "NoneType None" print type(NoneSample), repr(NoneSample) class Example(MyObject): def __init__(self, value): self.value = value @make_hook def add(self, other): return self.__class__(self.value + other.value) # Will unregister the class Example.unregister() inst = Example(10) # Will fail with an AttributeError #inst.unregister() print inst + inst class Sibling(MyObject): pass ExampleSibling = Example + Sibling # ExampleSibling is now a subclass of both Example and Sibling (with no # content of its own) although it will believe it's called 'AutoClass' print ExampleSibling print ExampleSibling.__mro__
@Kaniz開羅
一個元類是一個類的類。一個類定義了類的實例(對象)的行為,一個元類定義了一個類的行為。一個類是一個元類的一個實例。
雖然在Python中你可以使用任意的元類(如可調用的Jerub顯示),更好的方法是一個實際的類本身。類型通常是Python中的元類。類型本身就是一個類,它是它自己的類型。你不能重新創建類似於Python類型純粹,但Python欺騙。創建自己的Python中的元類你真的隻是想子類類型。
一個元類是最常用的類工廠。當你創建一個對象通過調用類,Python創建一個新類(它執行類的語句時)通過調用元類。結合正常__init__和__new__方法,因此元類允許你做額外的事情當創建一個類,如注冊新類和一些注冊表或完全用別的東西代替類。
執行類聲明時,Python首先執行的主體類聲明作為一個正常的代碼塊。由此產生的名稱空間(dict)類的屬性。元類是由觀察的baseclass類(元類都繼承了),在__metaclass__類的屬性(如果有的話)或__metaclass__全局變量。然後使用元類的名稱、基地和屬性的類來實例化它。
然而,元類定義類型類的,不僅僅是一個工廠,所以你可以做得更多。例如,您可以定義正常的元類上的方法。這些metaclass-methods是類方法一樣,他們可以被稱為類沒有實例,但他們也不像類方法,他們不能被稱為類的一個實例。type.__subclasses__()方法的一個例子在元類類型。您還可以定義正常的‘魔法’方法,像__add__ __iter__ __getattr__,實現或改變行為的類。這是一個聚合的例子的片段:
def make_hook (f):“”“裝飾將“foo”方法變成__foo__”“f。is_hook = 1返回f類MyType(類型):def __new__(製程、名稱、基地、attrs):如果name.startswith(“沒有”):返回沒有#超過屬性,看他們是否應該重新命名。newattrs = {} attrname, attrvalue attrs.iteritems():如果getattr (attrvalue is_hook, 0): newattrs[的__ % s__ % attrname] = attrvalue: newattrs [attrname] = attrvalue返回超級(MyType,製程)。__new__(製程、名稱、基地、newattrs) def __init__(自我、名稱、基地、attrs):超級(MyType,自我)。__init__(名稱、基地attrs) # classregistry。注冊(自我,self.interfaces)打印“現在注冊類% s。”% self def __add__(self, other): class AutoClass(self, other): pass return AutoClass # Alternatively, to autogenerate the classname as well as the class: # return type(self.__name__ + other.__name__, (self, other), {}) def unregister(self): # classregistry.unregister(self) print "Would unregister class %s now." % self class MyObject: __metaclass__ = MyType class NoneSample(MyObject): pass # Will print "NoneType None" print type(NoneSample), repr(NoneSample) class Example(MyObject): def __init__(self, value): self.value = value @make_hook def add(self, other): return self.__class__(self.value + other.value) # Will unregister the class Example.unregister() inst = Example(10) # Will fail with an AttributeError #inst.unregister() print inst + inst class Sibling(MyObject): pass ExampleSibling = Example + Sibling # ExampleSibling is now a subclass of both Example and Sibling (with no # content of its own) although it will believe it's called 'AutoClass' print ExampleSibling print ExampleSibling.__mro__