问题描述
我刚刚学习 Python,我有 C 背景,所以如果我对两者有任何混淆/混淆,请告诉我.
假设我有以下课程:
类节点(对象):def __init__(self, element):self.element = 元素self.left = self.right = 无@类方法def树(cls,元素,左,右):节点 = cls(元素)node.left = 左node.right = 正确返回节点
这是一个名为 Node
的类,它重载了构造函数,以便在需要时能够处理不同的参数.
仅在 __init__
中定义 self.element
(如上所示)与执行以下操作有什么区别:
类节点(对象):元素,左,右 = 无def __init__(self, element):self.element = 元素self.left = self.right = 无
__init__
中的self.element
不是和类的element
变量定义的一样吗?这不会将 element
从 None
覆盖到传递给 __init__
的 element
值吗?
一个是类属性,另一个是实例属性.它们是不同的,但它们以某种方式彼此密切相关,使它们有时看起来相同.
这与python查找属性的方式有关.有层次感.在简单的情况下,它可能如下所示:
实例 ->子类 ->超类 ->对象(内置类型)
当你像这样在 instance
上寻找一个属性时......
`instance.val`
...实际发生的是首先,Python 在实例本身中查找 val
.然后,如果它没有找到 val
,它会在它的类中查找,Subclass
.然后,如果在那里没有找到val
,它会在Subclass
、Superclass
的父级中查找.这意味着当你这样做时......
...Foo
share foovar
的所有实例,但都有自己独特的 selfvar
.下面是一个简单、具体的示例,说明其工作原理:
如果我们不接触foovar
,对于f
和Foo
来说都是一样的.但是如果我们改变 f.foovar
...
...我们添加了一个实例属性,它有效地屏蔽了 Foo.foovar
的值.现在如果我们直接改变 Foo.foovar
,它不会影响我们的 foo
实例:
但它确实影响了一个新的 foo
实例:
还要记住,可变对象增加了另一层间接性(正如 mgilson 提醒我的那样).此处,f.foovar
与 Foo.foovar
指代相同的对象,因此当您更改对象时,更改会沿层次结构向上传播:
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.
Assume I have the following class:
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
This is a class named Node
, that overloads the constructor, to be able to handle different arguments if needed.
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
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.
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)
When you look for an attribute on instance
like this...
`instance.val`
...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
...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
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
...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
But it does affect a new foo
instance:
>>> Foo(5).foovar
7
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 类成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!