問題描述
什么是方法屬性和數據屬性?它們之間有什么區別和共同點?
What is a method attribute, and a data attribute? What the difference between them and what they have in common?
我正在閱讀 python 2.7.9 (https://docs.python.org/2/tutorial/classes.html#random-remarks),突然兩者都變得難以理解.我會很感激它.
I was reading python 2.7.9 (https://docs.python.org/2/tutorial/classes.html#random-remarks) and suddenly both became hard to understand. I'll appreciate some light over it.
推薦答案
屬性是使用點語法在另一個對象上查找的變量:obj.attribute
.Python 的設計方式,屬性查找可以做各種各樣的事情,如果你不真正了解正在發生的事情,這種多樣性有時會導致錯誤(這是你鏈接到的文檔警告的內容).
An attribute is a variable that is looked up on another object using dot syntax: obj.attribute
. The way Python is designed, attribute lookups can do a variety of things, and that variety can sometimes lead to bugs if you don't really understand what is happening (this is what the documentation you linked to warns about).
最基本的問題是屬性查找可以找到存儲在對象實例字典中的值,也可以從對象的類(或基類,如果正在進行繼承)中找到某些內容.方法是存儲在類中的函數,但您通常通過在實例上查找它們來使用它們(它綁定"方法,在調用方法時將對象作為第一個參數插入).
The most basic issue is that an attribute lookup can find either a value stored in the object's instance dictionary, or it can find something from the object's class (or a base class, if there's inheritance going on). Methods are functions stored in the class, but you usually use them by looking them up on an instance (which "binds" the method, inserting the object as the first arguemnt when the method is called).
什么時候檢查的確切順序有點復雜(我在 an answer to another question),但在最基本的層面上,實例屬性通常優先于類屬性.
The exact sequence of what is checked when is a bit complicated (I described the full process in an answer to another question), but at the most basic level, instance attributes usually take precedence over class attribute.
如果同名的實例屬性和類屬性都存在,通常只能訪問實例屬性.如果不是故意的,這可能會非常令人困惑.
If an instance attribute and a class attribute with the same name both exist, usually only the instance attribute will be accessible. This can be very confusing if it is unintended.
考慮以下代碼:
class Foo(object):
def __init__(self, lst):
self.lst = lst
def sum(self):
self.sum = sum(self.lst)
return self.sum
f = Foo([1,2,3])
print(f.sum())
print(f.sum())
在這段代碼的底部,我們進行了兩次相同的調用.第一個工作正常,但第二個會引發異常.
At the bottom of this code, we make two identical calls. The first works just fine, but the second will raise an exception.
這是因為第一次查找 f.sum
時,我們在 Foo
類中找到了一個方法.我們可以毫無問題地調用該方法.問題在于 sum
方法將其計算結果(self.lst
中元素的總和)分配給一個也名為 的實例屬性總和
.這從視圖中隱藏了 sum
方法.
This is because the first time we look up f.sum
we find a method in the Foo
class. We can call the method with no problems. The trouble comes from the fact that the sum
method assigns the result of its calculation (the sum of the elements in self.lst
) to an instance attribute also named sum
. This hides the sum
method from view.
當第二個 f.sum()
調用查找 f.sum
時,它會找到包含整數 6
的實例屬性,而不是比預期的方法.整數是不可調用的,所以我們得到一個異常.
When second f.sum()
call looks up f.sum
, it finds the instance attribute, containing the integer 6
, rather than the expected method. An integer is not callable, so we get an exception.
解決方案當然是方法和屬性不要使用相同的名稱.上面的代碼是一個非常簡單的例子.在更復雜的代碼中由這類事情引起的錯誤可能更難以弄清楚.
The solution, of course, is not to use the same name for the method and attribute. The code above is a pretty trivial example. The bugs caused by this sort of thing in more complex code can be much more difficult to figure out.
如果您編寫的代碼向您不太了解的對象添加屬性,則應小心避免使用常用名稱.如果您正在編寫一個 mixin 類,請考慮在屬性名稱中使用兩個前導下劃線來觸發 Python 的名稱修飾,這正是為這種情況而設計的.
If you're writing code that adds attributes to objects you don't know much about, you should be careful to avoid common names. If you're writing a mixin class, consider using two leading underscores in the attribute names to trigger Python's name mangling, which is designed for exactly this sort of situation.
這篇關于數據屬性和方法屬性的區別的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!