问题描述
我只是在学习Python,我来自C语言,所以请让我知道我之间是否有混淆/混淆。
I am just learning Python and I come from a C background so please let me know if I have any confusion / mix up between both.
假设我拥有以下类:
class Node(object):
def __init__(self, element):
self.element = element
self.left = self.right = None
@classmethod
def tree(cls, element, left, right):
node = cls(element)
node.left = left
node.right = right
return node
这是一个名为 Node
的类,该类重载了构造函数,以便能够在需要时处理不同的参数。
This is a class named Node
, that overloads the constructor, to be able to handle different arguments if needed.
仅在 __ init __
中定义 self.element
有什么区别(如上所示),如下所示:相对于执行以下操作:
What is the difference between defining self.element
in __init__
only (as shown above) as opposed to doing the following:
class Node(object):
element, left, right = None
def __init__(self, element):
self.element = element
self.left = self.right = None
不是 self.element
在 __ init __
中与类的 element
相同定义的变量?难道不只是将 element
从 None
覆盖到 element
传递给 __ init __
的值?
Isn't self.element
in __init__
the same as the class's element
variable defined? Wouldn't that just overwrite element
from None
to the element
value passed into __init__
?
推荐答案
一个是类属性,而另一个是实例属性。它们是不同的,但是它们之间的紧密联系使它们有时看起来相同。
One is a class attribute, while the other is an instance attribute. They are different, but they are closely related to one another in ways that make them look the same at times.
它与python查找属性的方式有关。有一个层次结构。在简单的情况下,它可能看起来像这样:
It has to do with the way python looks up attributes. There's a hierarchy. In simple cases it might look like this:
instance -> Subclass -> Superclass -> object (built-in type)
在实例上查找属性时
就像这样...
`instance.val`
...实际上发生的是 first ,Python查找 val $实例本身中的c $ c>。然后,如果找不到
val
,它将查找其类 Subclass
。然后,如果在其中找不到 val
,它将查找 Subclass
的父级,超类
。这意味着您执行此操作...
...what actually happens is that first, Python looks for val
in the instance itself. Then, if it doesn't find val
, it looks in its class, Subclass
. Then, if it doesn't find val
there, it looks in the parent of Subclass
, Superclass
. This means that when you do this...
>>> class Foo():
foovar = 10
def __init__(self, val):
self.selfvar = val
... Foo
share foovar $的所有实例c $ c>,但有各自不同的
selfvar
s。下面是一个简单的具体示例:
...all instances of Foo
share foovar
, but have their own distinct selfvar
s. Here's a simple, concrete example of how that works:
>>> f = Foo(5)
>>> f.foovar
10
>>> Foo.foovar
10
如果我们不碰 foovar
,对于 f
和 Foo
都是一样的。但是如果我们更改 f.foovar
...
If we don't touch foovar
, it's the same for both f
and Foo
. But if we change f.foovar
...
>>> f.foovar = 5
>>> f.foovar
5
>>> Foo.foovar
10
...我们添加了一个有效掩盖该值的instance属性 Foo.foovar
。现在,如果我们直接更改 Foo.foovar
,它不会影响我们的 foo
实例:
...we add an instance attribute that effectively masks the value of Foo.foovar
. Now if we change Foo.foovar
directly, it doesn't affect our foo
instance:
>>> Foo.foovar = 7
>>> f.foovar
5
但这确实会影响新的 foo
实例:
But it does affect a new foo
instance:
>>> Foo(5).foovar
7
还请记住,可变对象会添加另一层间接(如米吉尔森提醒我)。在这里, f.foovar
指的是与 Foo.foovar
相同的对象,因此,当您更改对象时,更改
Also keep in mind that mutable objects add another layer of indirection (as mgilson reminded me). Here, f.foovar
refers to the same object as Foo.foovar
, so when you alter the object, the changes are propagated up the hierarchy:
>>> Foo.foovar = [1]
>>> f = Foo(5)
>>> f.foovar[0] = 99
>>> Foo.foovar
[99]
这篇关于Python类成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!