Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 防止成员对象引用同一列表_Python_List_Object - Fatal编程技术网

Python 防止成员对象引用同一列表

Python 防止成员对象引用同一列表,python,list,object,Python,List,Object,这应该很简单 class Object: x = 0 y = [] a = Object() b = Object() a.x = 1 b.x = 2 print a.x, b.x # output: 1 2 # works as expected a.y.append(3) b.y.append(4) print a.y, b.y # output: [3, 4] [3, 4] # same list is referenced how to fix? # desire

这应该很简单

class Object:
    x = 0
    y = []

a = Object()
b = Object()

a.x = 1
b.x = 2
print a.x, b.x
# output: 1 2
# works as expected

a.y.append(3)
b.y.append(4)
print a.y, b.y
# output: [3, 4] [3, 4]
# same list is referenced  how to fix?
# desired output: [3] [4]

据我所知,
a.y
b.y
引用了相同的列表。我怎样才能让他们分开?最好不要添加
\uuuu init\uuuu
方法。

在定义类时,只创建一次
y
的值。要为
y
的每个实例分配不同的列表,确实需要一个init函数。只需将
self.y=[]
放入
\uuuu init\uuuu
中,它就会按预期工作。

定义类时,您只需创建一次
y
的值。要为
y
的每个实例分配不同的列表,确实需要一个init函数。只需将
self.y=[]
放入
\uuuu init\uuuu
中,它就会按预期工作。

这里发生的事情是,实际上您已经将x重新定义为实例级别属性,并且您的类定义将它们都作为级别属性

如果你这样做,你可以看到你原来的x仍然是0

>>> Object.x
0
由于不创建新列表,因此它将使用class属性。如果要这样做:

>>> a.y = []
>>> b.y = []
>>> a.y.append(1)
>>> b.y.append(2)
>>> print a.y, b.y
[1] [2]
这就是你所期待的。实际上,您应该这样定义您的类:

class Object(object):
    def __init__(self):
        self.y = []
        self.x = 0

(不要将对象用作类名!)

这里发生的事情是,实际上您已经将x重新定义为一个实例级别属性,并且您的类定义将它们都作为级别属性

如果你这样做,你可以看到你原来的x仍然是0

>>> Object.x
0
由于不创建新列表,因此它将使用class属性。如果要这样做:

>>> a.y = []
>>> b.y = []
>>> a.y.append(1)
>>> b.y.append(2)
>>> print a.y, b.y
[1] [2]
这就是你所期待的。实际上,您应该这样定义您的类:

class Object(object):
    def __init__(self):
        self.y = []
        self.x = 0

(并且不要使用对象作为类名!)

设置实例属性而不是类属性的最简单方法是使用
\uuuu init\uuuu

当引用实例属性(如
a.y
)时,解析器会首先尝试返回该属性,但如果未找到该属性,则返回属性(
Object.y


在您的情况下,只定义了一个由所有实例共享的属性。

设置实例属性而不是属性的最简单方法是使用
\uu初始化

当引用实例属性(如
a.y
)时,解析器会首先尝试返回该属性,但如果未找到该属性,则返回属性(
Object.y


在您的情况下,只定义了一个由所有实例共享的属性。

唯一的方法是创建
\uuuuu init\uuu
方法

class Object:
  def __init__(self):
    self.x = 0
    self.y = []
这样,在构建对象时,一个新值将被分配到
x
,并为
y
创建一个新列表

您以前的操作方式为Object创建了两个类/静态变量,但只有
y
保持不变,因为它静态地只包含对true List的引用,反映了Object的所有实例

有关类/静态变量的更多信息,请参见另一个问题:


*抱歉,如果我使用了错误的术语,我更像是一个Java人;-)

唯一的方法是创建
\uuuu init\uuu
方法

class Object:
  def __init__(self):
    self.x = 0
    self.y = []
这样,在构建对象时,一个新值将被分配到
x
,并为
y
创建一个新列表

您以前的操作方式为Object创建了两个类/静态变量,但只有
y
保持不变,因为它静态地只包含对true List的引用,反映了Object的所有实例

有关类/静态变量的更多信息,请参见另一个问题:


*抱歉,如果我使用了错误的术语,我更像是一个Java人;-)

打印a.x,b,y应该打印:1[]这是
\uuuu init\uuuu
的用途。你为什么不想使用它?@gnibbler如果我知道Python对象是如何工作的,我就不会在这里了:)print a.x,b,y应该打印这个:1[]这就是
\uu init\uu
的用途。你为什么不想使用它?@gnibbler如果我知道Python对象是如何工作的,我就不会在这里:)很好的解释,谢谢!别担心,我真正的对象不是
Object
s:)漂亮的解释,谢谢!别担心,我真正的对象不是
Object
s:)