我正在閱讀有關將函式設定為類屬性時如何成為系結方法的資訊。然后我觀察到,由functools.partial. 對此有何解釋?
簡單的例子:
from functools import partial
def func1():
print("foo")
func1_partial = partial(func1)
class A:
f = func1
g = func1_partial
a = A()
a.f() # TypeError: func1() takes 0 positional arguments but 1 was given
a.g() # prints "foo"
我有點期望他們都以同樣的方式行事。
uj5u.com熱心網友回復:
允許函式成為系結方法的技巧是__get__魔術方法。
為了非常簡要地總結該頁面,當您訪問實體上的欄位時,例如foo.bar,Python 首先檢查是否bar存在于foo's中__dict__(或者__slots__,如果它有一個)。如果是,我們將其退回,不會造成任何傷害。如果沒有,那我們繼續看type(foo)。但是,當我們通過實體訪問類Foo.bar上的欄位時,會發生一些神奇的事情。當我們撰寫 時,假設沒有on 's (resp. ),那么我們實際上呼叫. 也就是說,Python 呼叫一個魔術方法來詢問物件希望如何檢索它。 Foofoo.barbarfoo__dict____slots__Foo.bar.__get__(foo, Foo)
這就是屬性的實作方式,也是系結方法的實作方式。在某個深處(可能是用 C 語言撰寫的),型別__get__上有一個函式,當通過實體訪問時系結該方法。 function
functools.partial,盡管看起來很像一個函式,但它不是型別的實體function。它只是一個碰巧實作的隨機類,__call__它沒有實作__get__。為什么不呢?好吧,他們可能只是認為這不值得,或者甚至可能沒有人考慮過。無論如何,“系結方法”技巧適用于被呼叫的型別function,而不是所有可呼叫物件。
關于魔術方法的另一個有用資源,__get__特別是:https ://rszalski.github.io/magicmethods/#descriptor
uj5u.com熱心網友回復:
型別function實作__get__方法:
>>> import types
>>> types.FunctionType.__get__
<slot wrapper '__get__' of 'function' objects>
partial才不是。
>>> from functools import partial
>>> partial.__get__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: type object 'functools.partial' has no attribute '__get__'. Did you mean: '__ge__'?
該__get__方法使a.f評估為 type 的值method而不是A.f. 沒有__get__,a.g就相當于A.g。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/526692.html
上一篇:類的多個成員被更新而不是一個
下一篇:在多個div上自動增加類標簽
