Python 列出 OO 编程中的别名或全局变量。不同的结果,同样的过程

标签 python oop global-variables alias

我知道 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/

相关文章:

python - 有没有办法将 "array of strings"设置为函数中参数的类型?

python - 通过属性更改内部字典的值

python - 将二维数组插入(更大的)二维数组的最快方法

python - Django Python loaddata 失败并出现 django.db.utils.IntegrityError

swift - 为什么不允许子类使用派生类型覆盖父类(super class)属性?

java - 使用 MVC 风格,调用查询函数的最佳位置在哪里?

c - 全局变量的替代方案 - GLUT C

oop - Scala 可以被视为 'Abstraction Inversion' 吗?

c - 全局指针值丢失。 2个文件

php - 为什么字符串 *RECURSION* 出现在输出中,并且每个包含的数组名称在 $GLOBALS 数组输出中都以下划线字符开头?