我有一个课程,例如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,因为var
字典是跨克隆馈送的。但是,如果我克隆克隆:
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
),因为它尚未被克隆。
我非常感谢您提供帮助或提示可以采取这种行为的适当技术。
答案 0 :(得分:1)
您遇到的问题是,当您使用**props
将其传递给新实例的__init__
方法时,您正在将计算克隆数量的整数复制。从那时起,就没有联系维持世代之间的计数。每个克隆父级及其克隆子级都将从相同的计数开始,但是谱系中的其他克隆数将分别计数。
要解决此问题,您需要将 all 实例从同一原始猫派生到与计数所处的单一来源相关联。我认为第一只未克隆的猫(血统的“祖先”)是它生活的最自然的地方,但是您可以这样做(例如,可以创建一个单独的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
通过这种设计,每个谱系只有一个 real 克隆计数,存储在祖猫实例的_clone_count
属性中。克隆世系中的所有猫都将能够访问该计数,并且clone_count
属性将其暴露给外部(无需其他代码就无需了解所有实现细节)。
答案 1 :(得分:1)
我建议您不要传递所有变量,而只是传递对列表的引用。因此,我们建立了两个规则:
1)任何不是通过克隆创建的猫都会创建自己的列表,并将其引用向下传递给任何克隆
2)任何通过克隆创建的猫都会从其父级获取引用,并将其传递给其他克隆。
最终结果是,来自同一只猫的所有猫都将对同一列表具有相同的引用。
这里是一个示例:
class Cat:
def __init__(self, parent=None):
if parent is None:
self.parent = [0]
else:
self.parent = parent
parent[0] += 1
def clone(self):
return Cat(self.parent)
@property
def clone_population(self):
return self.parent[0]
一些测试示例:
c = Cat()
print(c.clone_population)
>>>0
b = c.clone()
print(c.clone_population)
>>>1
d = b.clone()
print(c.clone_population, b.clone_population)
>>>2 2
答案 2 :(得分:1)
另一种方法可能是考虑使用某种类型的 <div class="topSlider">
<div class="slide"></div>
<div class="slide"></div>
<div class="slide"></div>
<div class="slide"></div>
</div>
元类。
这可能具有以下优势:能够定义CloneTrackers,根据所克隆的对象,该克隆提供不同的行为!
CloneTracker
例如:
class CloneTrackerSingleton(type):
def __init__(cls, name, bases, attrs, **kwargs):
super().__init__(name, bases, attrs)
cls._instance = None
def __call__(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = super().__call__(*args, **kwargs)
return cls._instance
class SimpleCloneTracker(metaclass=CloneTrackerSingleton):
def __init__(self):
self.total = 0
def inc(self):
self.total += 1
def get_total(self):
return self.total
class Cat:
def __init__(self):
self.tracker = SimpleCloneTracker()
@property
def clone_pop(self):
return self.tracker.get_total()
def clone(self):
SimpleCloneTracker().inc()
return Cat()