Python class 变量与所有实例共享
Python class variable is shared with all instances
class list_class:
def __init__(self, list_=[]):
self.list_ = list_
def add_item(self, item):
self.list_ += [item]
>>> x = list_class()
>>> y = list_class()
>>> x.list_
[]
>>> y.list_
[]
>>> x.add_item(1)
>>> x.list_
[1]
>>> y.list_
[1]
为什么在 x 上调用 add_item() 会更改两个实例上的 list_ 变量?
在方法参数中使用 list_=[]
是一个糟糕的 Python 习惯用法,原因您已经发现。请改用以下内容:
class ListClass:
def __init__(self, list_=None):
if list_ is None:
list_ = []
self.list_ = list_
def add_item(self, item):
self.list_.append(item)
当最初解析 __init__
时,list_
设置为 []
。但是,列表是可变的,不会在分配时复制。因此,当 __init__
方法为 运行 时,每次都使用相同的初始列表。通过上述替换,每次 __init__
为 运行 时,都会将 list_
分配给 new 列表,从而避免了该问题。这同样适用于 dict 作为函数参数值的默认值。列表或字典是空的还是包含值并不重要(__init__(self, list_=[5])
会遇到同样的问题:不要在函数参数中使用可变变量作为默认值。
参见the warning in the tutorial section of default function arguments。
其他更多 Pythonic 成语使用 CamelCase 作为 class 名称,并使用 somelist.append(item)
而不是 somelist += [item]
。
我见过几次,但不记得最终原因。解决方案是不(或永远)在 functions/classes.
中声明空的可迭代对象
class List_Class:
def __init__(self, list_):
self.list_ = list_
def add_item(self, item):
self.list_ += [item]
x = List_Class(list())
y = List_Class(list())
print(x.list_)
print(y.list_)
x.add_item(1)
print(x.list_)
print(y.list_)
class list_class:
def __init__(self, list_=[]):
self.list_ = list_
def add_item(self, item):
self.list_ += [item]
>>> x = list_class()
>>> y = list_class()
>>> x.list_
[]
>>> y.list_
[]
>>> x.add_item(1)
>>> x.list_
[1]
>>> y.list_
[1]
为什么在 x 上调用 add_item() 会更改两个实例上的 list_ 变量?
在方法参数中使用 list_=[]
是一个糟糕的 Python 习惯用法,原因您已经发现。请改用以下内容:
class ListClass:
def __init__(self, list_=None):
if list_ is None:
list_ = []
self.list_ = list_
def add_item(self, item):
self.list_.append(item)
当最初解析 __init__
时,list_
设置为 []
。但是,列表是可变的,不会在分配时复制。因此,当 __init__
方法为 运行 时,每次都使用相同的初始列表。通过上述替换,每次 __init__
为 运行 时,都会将 list_
分配给 new 列表,从而避免了该问题。这同样适用于 dict 作为函数参数值的默认值。列表或字典是空的还是包含值并不重要(__init__(self, list_=[5])
会遇到同样的问题:不要在函数参数中使用可变变量作为默认值。
参见the warning in the tutorial section of default function arguments。
其他更多 Pythonic 成语使用 CamelCase 作为 class 名称,并使用 somelist.append(item)
而不是 somelist += [item]
。
我见过几次,但不记得最终原因。解决方案是不(或永远)在 functions/classes.
中声明空的可迭代对象class List_Class:
def __init__(self, list_):
self.list_ = list_
def add_item(self, item):
self.list_ += [item]
x = List_Class(list())
y = List_Class(list())
print(x.list_)
print(y.list_)
x.add_item(1)
print(x.list_)
print(y.list_)