以下內摘自《Python
中的元類編程》
如果說類是對象執行個體的模板,那麼元類就是類的模板,類的工廠
清單 1.
老式的 Python 1.5.2
類工廠
Python 1.5.2 (#0, Jun 27 1999, 11:23:01) [...]
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> def class_with_method(func):
... class klass: pass
... setattr(klass, func.__name__, func)
... return klass
...
>>> def say_foo(self): print 'foo'
...
>>> Foo = class_with_method(say_foo)
>>> foo = Foo()
>>> foo.say_foo()
foo
工廠函數 class_with_method()
動態地建立一個類,並返回該類,這個類包含傳遞給該工廠的方法/函數。在返回該類之前,在函數體內操作類自身。 new
模組提供了更簡潔的編碼方式,但其中的選項與類工廠體內定製代碼的選項不同,例如:
清單 2. new
模組中的類工廠
>>> from new import classobj
>>> Foo2 = classobj('Foo2',(Foo,),{'bar':lambda self:'bar'})
>>> Foo2().bar()
'bar'
>>> Foo2().say_foo()
foo
元類的魔力
清單 3.
作為類工廠元類的 type
>>> X = type('X',(),{'foo':lambda self:'foo'})
>>> X, X().foo()
(<class '__main__.X'>, 'foo')
清單 4.
作為類工廠的 type
後代
>>> class ChattyType(type):
... def __new__(cls, name, bases, dct):
... print "Allocating memory for class", name
... return type.__new__(cls, name, bases, dct)
... def __init__(cls, name, bases, dct):
... print "Init'ing (configuring) class", name
... super(ChattyType, cls).__init__(name, bases, dct)
...
>>> X = ChattyType('X',(),{'foo':lambda self:'foo'})
Allocating memory for class X
Init'ing (configuring) class X
>>> X, X().foo()
(<class '__main__.X'>, 'foo')
清單 5.
將類方法附加在所產生的類上
>>> class Printable(type):
... def whoami(cls): print "I am a", cls.__name__
...
>>> Foo = Printable('Foo',(),{})
>>> Foo.whoami()
I am a Foo
>>> Printable.whoami()
Traceback (most recent call last):
TypeError: unbound method whoami() [...]
清單 6.
用類屬性設定元類
>>> class Bar:
... __metaclass__ = Printable
... def foomethod(self): print 'foo'
...
>>> Bar.whoami()
I am a Bar
>>> Bar().foomethod()
foo
參考:
Python
中的元類編程
Python
中的元類編程,第 2
部分
Python
中的元類編程,第 3
部分