Python类成员

dar*_*sky 45 python class member-variables

我只是在学习Python,而且我来自C背景,所以如果我在两者之间有任何困惑/混淆,请告诉我.

假设我有以下课程:

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
Run Code Online (Sandbox Code Playgroud)

这是一个名为的类Node,它重载构造函数,以便能够在需要时处理不同的参数.

是什么定义之间的差异self.element__init__只(如上所示),而不是执行以下操作:

class Node(object):
    element, left, right = None
    def __init__(self, element):
        self.element = element
        self.left = self.right = None
Run Code Online (Sandbox Code Playgroud)

是不是self.element__init__相同类的element变量定义?这难道不只是简单地覆盖elementNoneelement传入值__init__

sen*_*rle 70

一个是类属性,而另一个是实例属性.它们是不同的,但它们彼此密切相关的方式使它们看起来有时相同.

它与python查找属性的方式有关.有层次结构.在简单的情况下,它可能看起来像这样:

instance -> Subclass -> Superclass -> object (built-in type)
Run Code Online (Sandbox Code Playgroud)

当你在instance这样找一个属性时......

`instance.val`
Run Code Online (Sandbox Code Playgroud)

......实际发生的是,首先,Python val在实例中寻找.然后,如果它没有找到val,它会在它的类中查找Subclass.然后,如果它没有找到val那里,它看起来的父母Subclass,Superclass.这意味着当你这样做时......

>>> class Foo():
    foovar = 10  
    def __init__(self, val):
        self.selfvar = val
Run Code Online (Sandbox Code Playgroud)

......所有Foo 分享的 例子foovar,但都有自己独特selfvar的.这是一个简单,具体的例子:

>>> f = Foo(5)
>>> f.foovar
10
>>> Foo.foovar
10
Run Code Online (Sandbox Code Playgroud)

如果我们不碰foovar,这是两个相同的fFoo.但如果我们改变f.foovar......

>>> f.foovar = 5
>>> f.foovar
5
>>> Foo.foovar
10
Run Code Online (Sandbox Code Playgroud)

...我们添加一个有效掩盖值的实例属性Foo.foovar.现在,如果我们Foo.foovar直接更改,它不会影响我们的foo实例:

>>> Foo.foovar = 7
>>> f.foovar
5
Run Code Online (Sandbox Code Playgroud)

但它确实会影响一个新foo实例:

>>> Foo(5).foovar
7
Run Code Online (Sandbox Code Playgroud)

还要记住,可变对象添加了另一层间接(正如mgilson提醒我的那样).这里f.foovar指的是同一个对象Foo.foovar,因此当您更改对象时,更改会在层次结构中向上传播:

>>> Foo.foovar = [1]
>>> f = Foo(5)
>>> f.foovar[0] = 99
>>> Foo.foovar
[99]
Run Code Online (Sandbox Code Playgroud)

  • 很好的答案!在`Foo.foovar`是一个可变对象(例如`list`)的情况下,这些东西甚至会变得更有趣. (4认同)

Lee*_*ton 15

在python中,可以使用同名的类变量和实例变量.它们分别位于内存中,访问方式完全不同.

在你的代码中:

class Node(object):
    element, left, right = None
    def __init__(self, element):
        self.element = element
        self.left = self.right = None
Run Code Online (Sandbox Code Playgroud)

第一组变量(在__init__函数外部)称为类变量.这些可以随后使用Node.element等访问.这些等同于C++中的静态成员变量,并且它们由类的所有实例共享.

第二组变量(在__init__函数内)称为实例变量.这些可以通过self对象访问,例如self.element,或者通过实例名称访问,例如myNode.element在类之外.

重要的是要注意,您必须使用self.variableNode.variable表单从成员函数中访问其中任何一个.只是访问variable将尝试访问一个名为的局部变量variable.