数据属性和方法属性之间的差异

时间:2015-03-01 20:39:19

标签: python methods attributes

什么是方法属性和数据属性?他们和他们有什么共同之处有什么区别?

我正在阅读python 2.7.9(https://docs.python.org/2/tutorial/classes.html#random-remarks),突然之间变得难以理解。 我会对它有所了解。

5 个答案:

答案 0 :(得分:22)

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

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

检查时的确切顺序有点复杂(我在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中的元素之和)分配给名为sum的实例属性。这会隐藏sum方法。

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

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

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

答案 1 :(得分:9)

属性是缺少绑定到对象的更好单词的任何东西,例如:

class Dog:
    def __init__(self):
        self.name = "Rufus"

    def bark(self):
        print "Woof Woof!"

在这种情况下,data属性是名称,它只是绑定到Dog实例的值。至于方法属性,一个答案是树皮方法,因为它不是一个值,而是一个动作。它和英语一样。数据属性与听起来完全一样;它的数据,它只是一个属性。方法是一个过程,一个动作,这正是方法属性。

答案 2 :(得分:3)

以下是对您的问题的直接解释,这有助于我理解属性和方法之间的区别。

类就像是如何构建许多共享特征的对象的一组指令或蓝图。

对象是根据类定义提供的规范构建的数据类型。

属性是值(特征)。将属性视为存储在对象中的变量。

方法是一组指令。方法是与对象相关联的函数。父类定义中包含的任何函数都可以由该类的对象调用。

我希望这会有所帮助。

答案 3 :(得分:2)

属性基本上是您可以instance.attribute_name执行的任何操作。例如:

class Hello(object):
    def __init__(self, word):
        self.word = word

    def greet(self):
        print "Hello: "+self.word

__init__greetword都属于属性。我猜想一个方法是在类范围内用def声明的任何东西(而不是做self.func = lambda x:x * x)。在这种情况下,您将进入绑定与未绑定方法等。重要的一点是,当你执行instance.method_name时,对于一个成员属性,你会得到一个绑定方法,当你调用它时,它将调用原始方法,并将实例作为第一个参数。

此外,在阅读了部分内容后,他们的措辞有些令人困惑/错误。例如,他们说“数据属性覆盖具有相同名称的方法属性”,据我所知,最好将其作为实例属性覆盖具有相同名称的类属性。从我给出的例子中我们将其扩展为:

class Hello(object):
    greeting = "Hello: "
    def __init__(self, word):
        self.word = word

    def greet(self):
        print self.greeting+self.word

然后我们可以这样做:

>>> a = Hello("world")
>>> a.greeting = "Goodbye "
>>> a.greet()
"Goodbye world"

这是因为我们将greeting的实例属性放在greeting的class属性上。由于类中定义的方法(通常的方式)是类属性,因此它们将被任何实例属性(数据或其他)覆盖。

答案 4 :(得分:0)

属性描述对象,而方法对对象起作用并对其进行更改。