简体   繁体   English

奇怪的Python行为 - 或者我错过了什么

[英]Weird Python behaviour - or am I missing something

The following code: 以下代码:

class House:
    links = []

class Link:
    pass

class Villa(House):
    pass

if __name__ == '__main__':
    house = House()
    villa = Villa()
    link = Link()
    house.links.append(link)

    print house.links
    print villa.links

results in this output: 结果输出:

[<__main__.Link instance at 0xb65a4b0c>] 
[<__main__.Link instance at 0xb65a4b0c>]

I find this very weird: Since it is another instance? 我觉得这很奇怪:既然是另一个例子? - I would have expected that the output is - Since it is another instance?: - 我原以为输出是 - 因为它是另一个实例?:

[<__main__.Link instance at 0xb65a4b0c>] 
[]

When changing the line house.links.append(link) to house.links = [link] everything works as expected. 当更改行house.links.append(link)house.links = [link]一切都按预期工作。

Can somebody explain this behavior? 有人可以解释这种行为吗?

It is another instance, but you have defined links as a class variable rather than an instance variable. 它是另一个实例,但您已将links定义为类变量而不是实例变量。

An instance variable would be defined as such: 实例变量将被定义为:

class House(object):  # Always use new-style classes except for backward compatibility
  def __init__(self):
    self.links = []

Note that in Python, unlike other languages, an instance variable is explicitly declared to be a property of an instance. 请注意,在Python中,与其他语言不同,实例变量显式声明为实例的属性。 This usually happens in the __init__ method, to ensure that every instance has the variable. 这通常发生在__init__方法中,以确保每个实例都有变量。

Then, the subclass would look like this: 然后,子类看起来像这样:

class Villa(House):
  def __init__(self):
    super(Villa, self).__init__()

And executing your code gives the correct results: 执行代码会得到正确的结果:

>>> house = House()
>>> villa = Villa()
>>> link = Link()
>>> house.links.append(link)
>>> print house.links
[<__main__.Link instance at 0xcbaa8>]
>>> print villa.links
[]

In your code, links is an attribute on the class, making it shared by all instances of that class: 在您的代码中, links是类的一个属性,使其由该类的所有实例共享:

class House:
    links = []

Because of this, your Villa class shares this attribute, because an instance of Villa is (as a subclass) also an instance of House . 因此,您的Villa类共享此属性,因为Villa的实例(作为子类)也是House的实例。

If you want to make links an instance variable, write a constructor and set links as an attribute of self , eg 如果要将links作为实例变量,请编写构造函数并将links设置为self的属性,例如

class House:
    def __init__(self):
        self.links = []

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM