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

Differences between data attributes and method attributes

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

我正在阅读 python 2.7.9 (https://docs.python.org/2/tutorial/classes.html#random-remarks) 突然变得难以理解。 我将不胜感激。

属性是指缺少与对象绑定的更好词的任何事物,例如:

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

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

在这种情况下,数据属性是名称,它只是一个绑定到 Dog 实例的值。至于方法属性,一个答案是树皮方法,因为它与其说是一个值,不如说是一个动作。就像英语一样。数据属性顾名思义;它是数据,它只是一个 属性。方法是一个过程,一个动作,这正是方法属性。

属性基本上是您可以instance.attribute_name使用的任何东西。例如:

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

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

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

此外,在阅读了该部分的一些内容后,他们的措辞有些 confusing/erroneous。例如,他们说 "Data attributes override method attributes with the same name",据我所知最好将其作为实例属性覆盖同名的 class 属性。从我给出的示例中,如果我们将其扩展为:

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 属性之上。由于 class(通常的方式)中定义的方法是 class 属性,它们将被任何实例属性(数据或其他)覆盖。

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

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

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

如果同名的实例属性和class属性同时存在,通常只有实例属性可以访问。如果这是无意的,这可能会非常混乱。

考虑以下代码:

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时我们在Fooclass中找到了一个方法。我们可以毫无问题地调用该方法。问题在于 sum 方法将其计算结果(self.lst 中元素的总和)赋值给了一个同样名为 sum 的实例属性。这从视图中隐藏了 sum 方法。

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

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

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

这是对你的问题的直接解释,它帮助我理解了属性和方法之间的区别。

class 就像一组说明或蓝图,用于构建许多具有共同特征的对象。

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

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

方法是一组指令。方法是与对象关联的函数。父 class 定义中包含的任何函数都可以被该 class.

的对象调用

希望对您有所帮助。

属性描述对象,而方法作用于对象并改变它。