![](/img/trans.png)
[英]What happens if I attribute a second instance of a class with the same variable holding an existing instance?
[英]python: What happens when class attribute, instance attribute, and method all have the same name?
當名稱相同時,python如何區分類屬性,實例屬性和方法?
class Exam(object):
test = "class var"
def __init__(self, n):
self.test = n
def test(self):
print "method : ",self.test
test_o = Exam("Fine")
print dir(test_o)
print Exam.test
print test_o.test
test_o.test()
輸出:
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'test']
<unbound method load.test>
Fine
Traceback (most recent call last):
File "example.py", line 32, in <module>
test_o.test()
TypeError: 'str' object is not callable
怎么打電話
Exam.test
- > <unbound method load.test>
輸出顯示方法 test_o.test
- > "Fine"
test_o.test()
- > TypeError: 'str' object is not callable
可以通過類訪問類屬性:
YourClass.clsattribute
或者通過實例(如果實例沒有覆蓋class屬性):
instance.clsattribute
在他的回答中 , ecatmur所述的方法是描述符,並被設置為類屬性。
如果通過實例訪問方法,則實例將作為self
參數傳遞給描述符。 如果要從類中調用方法,則必須顯式傳遞實例作為第一個參數。 所以這些是等價的:
instance.method()
MyClass.method(instance)
對實例屬性和方法使用相同的名稱將使該方法通過實例隱藏,但該方法仍可通過類獲得:
#python3
>>> class C:
... def __init__(self):
... self.a = 1
... def a(self):
... print('hello')
...
>>> C.a
<function a at 0x7f2c46ce3c88>
>>> instance = C()
>>> instance.a
1
>>> C.a(instance)
hello
結論:不要為實例屬性和方法指定相同的名稱。 我通過給出有意義的名字來避免這種 方法是動作,所以我通常使用動詞或句子。 屬性是數據,因此我使用名詞/形容詞,這避免了對方法和屬性使用相同的名稱。
請注意,您不能擁有與方法同名的class屬性,因為該方法將完全覆蓋它(最后,方法只是可調用的類屬性,並自動接收類的實例作為第一個屬性) 。
你可以寫
Exam.test(test_o)
要么
Exam.test.__get__(test_o)()
在后一種情況下,您使用的方法是將<unbound method load.test>
轉換為<unbound method load.test>
描述符 ,因此您可以使用單括號調用它。
當您編寫test_o.test()
,Python不知道您正在嘗試調用方法; 您可能正在嘗試將作為實例數據成員安裝在對象上的函數或可調用對象調用。 相反,它首先查找屬性test
,然后查找對象,然后查看其類,但由於該屬性存在於對象上,因此它會隱藏類上的方法。
班級成員
test = "class var"
是不可訪問的(實際上它不存在於任何地方),因為它被方法test
覆蓋; 執行class
語句時,其名稱空間在傳遞給其元類之前被收集到dict中,后來的名稱會覆蓋之前的名稱。
您可以將方法作為類方法調用並將您的實例傳遞給它:
Exam.test(test_o)
或者,如果您不想使用Exam
:
type(test_o).test(test_o)
怎么打電話
class屬性,Exam.test
你不能,因為在執行def test(self)
,名稱test
綁定到類中的方法,並且對"class var"
的引用將丟失。
實例屬性
test_o.test
- >“精細”
你已經這樣做了。
方法
test_o.test()
您無法以這種方式調用它,因為在執行self.test = n
,名稱test
將綁定到實例中的任何對象n
引用,並且實例中對方法的引用將丟失。
但正如其他答案中所指出的,您可以在類中調用該方法並將實例傳遞給它: Exam.test(test_o)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.