首页 > 解决方案 > 跨多个类实例(但不是所有实例)的共享属性

问题描述

我有一个类,说Cat我目前定义如下。

class Cat:
    def __init__(self, clone_population=0, **kwargs):
        self.clone_population = clone_population

    def clone(self):
       props = vars(self)
       props['clone_population'] += 1
       return Cat(**props)

猫可以通过直接实例化它们来出生(出生猫),也可以从其他猫中克隆出来。

现在,我想不通的是如何跟踪给定出生猫的克隆种群,以便出生猫本身及其所有克隆都可以访问种群数量

示例,基于当前代码(这是我所在的位置)

cat_mandu = Cat()  # A new cat is born 
cat_mandu.clone_population
# 0

正如预期的那样,我们还没有克隆。如果我做一个克隆:

cat_mandu_v2 = cat_mandu.clone()  # catmandu is cloned
cat_mandu.clone_population, cat_mandu_v2.clone_population
# 1, 1

现在,我正确地得到了出生猫和克隆猫的 1,因为vardict 是通过克隆提供的。但是,如果我克隆克隆:

cat_mandu_v3 = cat_mandu_v2.clone()  # clone the clone
cat_mandu.clone_population, cat_mandu_v2.clone_population, cat_mandu_v3.clone_population
# 1, 2, 2

我没有在出生猫中更新人口。我希望我的行为有一个属性来跟踪给定出生猫的克隆数量,并且出生者及其所有克隆都跟踪与当前克隆种群相同的数字。所以正确的答案应该是2 2 2而不是1 2 2

请注意,如果一只新出生的猫meawsome = Cat()出生了,我们应该只看到 0 个克隆种群 ( meawsome.clone_population = 0),因为它还没有被克隆。

我感谢可以提供此类行为的适当技术的帮助或提示。

标签: pythonpython-3.xclass

解决方案


**props您遇到的问题是,当您将整数传递给新实例的__init__方法时,您正在复制计算克隆数的整数。从那时起,保持世代之间的计数就没有联系了。每个克隆父母和他们的克隆孩子将以相同的计数开始,但血统中的其他人将单独计数。

要解决此问题,您需要将源自同一原始猫的所有实例链接到计数所在的单个源。我认为第一只未克隆的猫(血统的“祖先”)是它最自然的生活场所,但你可以做其他事情(例如,你可以创建一个单独的Lineage类)。这是我的做法:

class Cat:
    def __init__(self, progenitor=None):
        if progenitor is None:
            self._clone_count = 0
            self.progenitor = self
        else:
            self.progenitor = progenitor

    def clone(self):
        self.progenitor._clone_count += 1
        return Cat(self.progenitor)

    @property
    def clone_count(self):
        return self.progenitor._clone_count

通过这种设计,每个谱系只有一个真正的克隆计数,存储在祖先猫实例的_clone_count属性中。尽管如此,克隆谱系中的所有猫都将能够访问该计数,并且该clone_count属性将其暴露给外部(无需其他代码知道所有实现细节)。


推荐阅读