我知道 a+=b 和 a=a+b 并不总是给出相同的结果,具体取决于它们引用的内容(如果我错了,请纠正我)。 我还知道 Python 中的列表别名问题。参见这里:(Yet Another) List Aliasing Conundrum
下面的问题似乎都不是这些,所以我不确定问题是什么。
我有以下程序。特别注意add_clouds()的最后一行和add_hosts()的最后一行。
在此处定义全局变量和类
global REQUESTS
global CLOUDS
REQUESTS = []
CLOUDS = []
class Cloud:
def __init__(self, ID, coordinate, Hosts):
self.ID = ID
self.coordinate = coordinate # coordinate should be a tuple
self.Hosts = Hosts # Hosts should be a list of Host objects
class Host:
def __init__(self, ID, Resources, Cloud):
self.ID = ID
self.Resources = Resources # coordinate should be a tuple
self.Cloud = Cloud # Cloud object (NOT the Cloud ID)
这部分生成云和主机
def add_cloud(ID,coordinate,Hosts=[]):
global CLOUDS
CLOUDS += [Cloud(ID, coordinate, Hosts)]
def add_host(Cloud_ID, Resources):
# search CLOUDS for Cloud_ID
Cloud = getCloud(Cloud_ID)
ID = len(Cloud.Hosts)+1
Cloud.Hosts += [Host(ID,Resources,Cloud)]
def getCloud(ID):
# returns cloud with ID provided
for cloud in CLOUDS:
if ID == cloud.ID:
return cloud
add_cloud(1,(10.7,13.5))
add_cloud(2,(1.8,3.0))
add_host(1,128)
shell 中的结果:
>>> CLOUDS
[<Cloud_Traversal.Cloud instance at 0x027336C0>, <Cloud_Traversal.Cloud instance at 0x02733DF0>]
>>> CLOUDS[1].Hosts
[<Cloud_Traversal.Host instance at 0x027334E0>]
>>> CLOUDS[0].Hosts
[<Cloud_Traversal.Host instance at 0x027334E0>]
>>>
您可以看到主机以某种方式添加到两个云中,即使我只是明确地将其添加到一个云中(在 add_host(1,128) 行中)。
我试图看看这是否是一个别名问题,但我不认为我在这里违反了任何规则。你知道可能出现什么问题吗?
最佳答案
请参阅此帖子:"Least Astonishment" and the Mutable Default Argument
当Python执行以下代码时:
def add_cloud(ID,coordinate,Hosts=[]):
global CLOUDS
CLOUDS += [Cloud(ID, coordinate, Hosts)]
它创建一个函数对象,并存储在属性 func_defaults
下的元组中指定的默认参数值。请参阅:
>>> print add_cloud.func_defaults
([],)
所以基本上默认参数总是引用相同的列表。而且您的云也都将保存指向同一列表的指针,因此向一个云添加主机将影响所有其他云,包括您将来可能创建的任何新云。
要防止这种情况,请执行以下操作:
def add_cloud(ID,coordinate,Hosts=None):
if Hosts is None:
Hosts = []
global CLOUDS
CLOUDS += [Cloud(ID, coordinate, Hosts)]
还有一个great effbot article关于这个话题。
关于Python 列出 OO 编程中的别名或全局变量。不同的结果,同样的过程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27848858/