[英]Avoiding creating new method object
根據Python 2.7.12文檔,
當屬性是用戶定義的方法對象時,僅當要從中檢索該屬性的類與原始方法對象中存儲的類相同或派生出類時,才創建新的方法對象; 否則,將按原樣使用原始方法對象。
我試圖通過編寫代碼來理解本段:
# Parent: The class stored in the original method object
class Parent(object):
# func: The underlying function of original method object
def func(self):
pass
func2 = func
# Child: A derived class of Parent
class Child(Parent):
# Parent.func: The original method object
func = Parent.func
# AnotherClass: Another different class, neither subclasses nor subclassed
class AnotherClass(object):
# Parent.func: The original method object
func = Parent.func
a = Parent.func
b = Parent.func2
c = Child.func
d = AnotherClass.func
print b is a
print c is a
print d is a
輸出為:
False
False
False
我希望它是:
False
False
True
每次編寫Parent.func
,都會得到一個新的未綁定方法對象。 因此, AnotherClass.func
永遠不會更改,而Parent.func
會更改。 如果您執行以下操作,則可以看到以下內容:
a = Parent.func
a2 = Parent.func
b = Parent.func2
c = Child.func
d = AnotherClass.func
d2 = AnotherClass.func
然后:
>>> a is a2
False
>>> d is d2
True
因此,您對“原始方法對象”的評論有些誤導。 代碼中評估Parent.func
每個部分都獲得一個不同的方法對象。 (請注意,您提供的引號不適用於Parent.func
,因為在Parent
編寫的func
不是方法對象;它是函數對象。只有通過編寫Parent.func
來訪問屬性時,您才能獲得方法對象。)
我在這里添加一些內容以澄清您的報價。
我認為您誤解了那句話的意思。 這可能是因為引號對於“屬性”和通過獲取該屬性而獲取的值之間的區別有些含糊。
讓我通過分開兩個概念來澄清。 在諸如something.attr
類的表達式中,我將使用“原始值”來引用存儲在類/對象字典中的實際值,即something.__dict__['attr']
。 我將使用“評估值”來指代對something.attr
進行評估的實際結果。 兩者之間的區別在於, 描述符協議在原始值上被激活以獲得評估值。
您引用的文檔描述了原始值是方法對象的情況。 您對Child和AnotherClass的定義就是這種情況。 報價不適用於func
內家長,因為在這種情況下,原始值是不是方法; 這是一個功能。 在這種情況下,文檔的以下段落適用:
通過檢索用戶定義的函數對象創建用戶定義的方法對象時...
換句話說,您引用的文檔(“當屬性是用戶定義的方法對象時”)適用於以下情況:
obj = [a method object]
class Foo(object):
attr = obj
您引用的文檔不適用於以下情況。 在這種情況下,屬性是“用戶定義的函數對象”:
func = [a function object]
class Foo(object):
attr = func
在您的示例中,沒有“原始方法對象”。 定義類后 ,您只能獲取方法對象。 “原始”對象是功能對象。 當您在類主體中編寫func
時,您正在定義一個函數。 只有在訪問 Parent.func
,您才能獲得方法對象。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.