簡體   English   中英

避免創建新的方法對象

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM