python - 数据属性和方法属性的区别

标签 python methods attributes

什么是方法属性和数据属性?它们之间有什么区别和共同点?

我正在阅读 python 2.7.9 ( https://docs.python.org/2/tutorial/classes.html#random-remarks ),突然两者都变得难以理解。 我会很感激它。

最佳答案

属性是使用点语法在另一个对象上查找的变量:obj.attribute。 Python 的设计方式,属性查找可以做各种各样的事情,如果你不真正了解正在发生的事情,这种多样性有时会导致错误(这是你链接到的文档警告的内容)。

最基本的问题是属性查找可以找到存储在对象实例字典中的值,也可以从对象的类(或基类,如果正在进行继承)中找到某些内容。方法是存储在类中的函数,但您通常通过在实例上查找它们来使用它们(它“绑定(bind)”方法,在调用方法时将对象作为第一个参数插入)。

什么时候检查的确切顺序有点复杂(我在 an answer to another question 中描述了完整的过程),但在最基本的层面上,实例属性通常优先于类属性。

如果同名的实例属性和类属性都存在,通常只能访问实例属性。如果不是故意的,这可能会非常令人困惑。

考虑以下代码:

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())

在这段代码的底部,我们进行了两次相同的调用。第一个工作正常,但第二个会引发异常。

这是因为第一次查找 f.sum 时,我们在 Foo 类中找到了一个方法。我们可以毫无问题地调用该方法。问题在于 sum 方法将其计算结果(self.lst 中元素的总和)分配给一个也名为 的实例属性总和。这从 View 中隐藏了 sum 方法。

当第二个 f.sum() 调用查找 f.sum 时,它会找到包含整数 6 的实例属性,而不是比预期的方法。整数是不可调用的,所以我们得到一个异常。

解决方案当然是方法和属性不要使用相同的名称。上面的代码是一个非常简单的例子。在更复杂的代码中由这类事情引起的错误可能更难以弄清楚。

如果您编写的代码向您不太了解的对象添加属性,则应小心避免使用常用名称。如果您正在编写一个 mixin 类,请考虑在属性名称中使用两个前导下划线来触发 Python 的名称修饰,这正是为这种情况而设计的。


附录:文档试图区分数据和非数据描述符也是可能的。方法是最常见的非数据描述符,因此将它们称为“方法属性”可能在一定程度上有意义(尤其是与“数据属性”相反,后者是数据描述符的对应名称),尽管我我不知道这种语言被更广泛地使用。两种描述符之间的重要区别在于数据描述符(如 property)在检查实例字典以查找普通实例变量之前得到处理。如上所述,非数据描述符(如方法)仅在检查实例字典后被处理,因此它们可以被存储在实例上的数据所掩盖。

关于python - 数据属性和方法属性的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28798781/

相关文章:

Python:如何向数据帧的索引和列添加缺失值?

python - Pandas GroupBy 全部应用

jquery - 自定义 jQuery 方法创建

python - 在对象列表中获取具有最大属性值的对象

c# - 关于 NUnit TestFixtureTeardown 属性

c# - 检查参数是否具有值的 MVC 操作属性?

python - 有没有更好的方法来获取字典列表中的字典值?

python - python中的递归函数不会自行调用

python - 如何在单元测试中重用单元测试方法而不实际测试它

java - Java 接口(interface)中的可选方法