該omnimethod是非常聰明的。它使用一些非常微妙的技巧來完成它的工作。讓我們從頭開始。
你可能已經知道,decorator syntax是功能應用只是糖,即:
@somedecorator
def somefunc(...):
pass
# is the same thing as
def somefunc(...):
pass
somefunc = somedecorator(somefunc)
所以somefunc
實際上是一個omnimethod
實例,而不是已經定義的功能。有趣的是omnimethod
也實現了descriptor
interface.如果一個類屬性定義了一個__get__
方法,那麼無論何時提及該屬性,解釋器都會在該對象上調用__get__
,然後返回該屬性,而不是返回屬性本身。
__get__
方法總是以實例作爲第一個參數,並將該實例的類作爲第二個參數調用。如果該屬性實際上是從類本身查找的,則實例將是None
。
最後一個詭計是functools.partial
,這是函數currying的python方式。當你使用partial
時,你給它傳遞一個函數和一些參數,並且它返回一個新的函數,當被調用時,除了後面你傳入的任何參數外,還會用原始參數調用原始函數。 omnimethod
使用此技術爲其包裝的函數填充self
參數。
這是看起來像什麼。一個regular method可以在你從一個實例中讀取時被調用,但你不能從這個類本身使用它。你會得到一個綁定類型錯誤
>>> class Foo(object):
... def bar(self, baz):
... print self, baz
...
>>> f = Foo()
>>> f.bar('apples')
<__main__.Foo object at 0x7fe81ab52f90> apples
>>> Foo.bar('quux')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unbound method bar() must be called with
Foo instance as first argument (got str instance instead)
>>> Foo.bar(None, 'quux')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unbound method bar() must be called with
Foo instance as first argument (got NoneType instance instead)
>>>
Python提供了bultin裝飾classmethod
(也staticmethod
,但是沒關係那),這將讓你在類級別使用它,但它從來沒有得到看到的實例。它總是接收該類,因爲它的第一個參數。
>>> class Foo(object):
... @classmethod
... def bar(cls, baz):
... print cls, baz
...
>>> f = Foo()
>>> Foo.bar('abc')
<class '__main__.Foo'> abc
>>> f.bar('def')
<class '__main__.Foo'> def
>>>
通過它的聰明一點,omnimethod
提供給你的一點點。
>>> class Foo(object):
... @omnimethod
... def bar(self, baz):
... print self, baz
...
>>> f = Foo()
>>> Foo.bar('bananas')
None bananas
>>> f.bar('apples')
<__main__.Foo object at 0x7fe81ab52f90> apples
>>>
http://wiki.python.org/moin/PythonDecorators#What_is_a_Decorator – krs1
如果無法找出property'是什麼',你的谷歌福需要工作:搜索「蟒蛇財產」和你快速獲取像http://docs.python.org/library/functions.html#property這樣的內容。並從那裏到像http://docs.python.org/glossary.html#term-decorator –