问题描述
什么是方法属性和数据属性?它们之间有什么区别和共同点?
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.
这篇关于数据属性和方法属性的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!