在一个类变量中收集所有实例总是不好的吗?



考虑存储云位置的简单天气模型的两个版本:

class cloud:
    def __init__(self, x, y):
        self.x = x
        self.y = y
collection = []
collection.append(cloud(1,2))
collection.append(cloud(4,6))
def update_all_clouds(collection):
    for c in collection:
        cloud.x += 1
        cloud.y += 1
update_all_clouds(collection)

class cloud:
    collection = []
    def __init__(self, x, y)
        self.x = x
        self.y = y
        cloud.collection.append(self)
    @classmethod
    def update_all(cls):
        for c in cloud.collection:
            c.x += 1
            c.y += 1
cloud(1,2)
cloud(4,6)
cloud.update_all()

这基本上已经被惩罚了将一个类的所有实例存储在一个类字段中是不好的吗?但是这里强调的是作用于所有实例的类方法。第二种方法所提供的最后三行字的简单性,难道没有什么可说的吗?

我知道另一种方法是创建一个类似列表的类,例如,集合,并给出类的方法,如update_all(),但对我来说,它似乎没有更好。

一般来说,这是不好的,原因很简单,列表中的对象几乎永远保持对它们的引用。对对象的引用可以防止它被垃圾收集。因此,你的类型的对象本质上是永久存在的(直到程序终止),它们占用的内存永远不会被释放。

当然,如果您有非常具体的需要,并且完全控制何时创建对象,则可以这样做。但一般来说,显式比隐式好,所以最好有一个实际的集合来添加这些元素。该集合甚至可以存在于类型中,因此您可以这样做:

obj = Cloud(…)
Cloud.add(obj)
# or even
obj = Cloud(…).persistInType()

您也可以使用弱引用来避免上述问题,但这是额外的开销,并且管理起来有点复杂。所以帮你自己一个忙,手动收集这些对象。

考虑到显式优于隐式(参见Python的禅意),也许最好的方法是有两个类:CloudCloudCollection。这将允许您编写这样的代码:

collection = CloudCollection()
collection.add(Cloud(1, 2))
collection.add(Cloud(4, 6))
collection.shift(1, 1)

这个问题可以简单地简化为关于使用全局变量的问题,因为可变的类级成员只是不同命名空间中的全局变量。

所有反对使用全局变量的参数也适用于此

相关内容

  • 没有找到相关文章

最新更新