简体   繁体   English

蟒蛇。 奇怪的类属性行为

[英]Python. Strange class attributes behavior

>>> class Abcd:

...     a = ''
...     menu = ['a', 'b', 'c']
... 
>>> a = Abcd()
>>> b = Abcd()
>>> a.a = 'a'
>>> b.a = 'b'
>>> a.a
'a'
>>> b.a
'b'

It's all correct and each object has own 'a', but... 都是正确的,每个对象都有自己的“ a”,但是...

>>> a.menu.pop()
'c'
>>> a.menu
['a', 'b']
>>> b.menu
['a', 'b']

How could this happen? 怎么会这样 And how to use list as class attribute? 以及如何使用列表作为类属性?

This is because the way you're initializing the menu property is setting all of the instances to point to the same list, as opposed to different lists with the same value. 这是因为初始化menu属性的方式是将所有实例设置为指向同一列表,而不是具有相同值的不同列表。

Instead, use the __init__ member function of the class to initialize values, thus creating a new list and assigning that list to the property for that particular instance of the class: 而是使用类的__init__成员函数初始化值,从而创建一个新列表,并将该列表分配给该类的特定实例的属性:

class Abcd:
    def __init__(self):
        self.a = ''
        self.menu = ['a', 'b', 'c']

See class-objects in the tutorial, and notice the use of self . 请参阅本教程中的类对象 ,并注意使用self

Use instance attributes, not class attributes (and also, new style classes) : 使用实例属性,而不是类属性(以及新样式类):

>>> class Abcd(object):
...     def __init__(self):
...         self.a = ''
...         self.menu = ['a','b','c']
...         
>>> a=Abcd()
>>> b=Abcd()
>>> a.a='a'
>>> b.a='b'
>>> a.a
'a'
>>> b.a
'b'
>>> a.menu.pop()
'c'
>>> a.menu
['a', 'b']
>>> b.menu
['a', 'b', 'c']
>>> 

because variables in Python are just "labels" 因为Python中的变量只是“标签”

both Abcd.menu and a.menu reference the same list object. Abcd.menu和a.menu都引用同一个列表对象。

in your case you should assign the label to a new object, 您应该将标签分配给新对象,

not modify the object inplace. 不就地修改对象。

You can run 你可以跑

a.menu = a.menu[:-1]

instead of 代替

a.menu.pop()

to feel the difference 感受不同

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

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