我为我正在进行的一些实验室实验的结果定义了一个名为Experiment
的类。我的想法是创建一种数据库:如果我添加一个实验,这将在退出之前被腌制到数据库并在启动时重新加载(并添加到类注册表中)。
我的班级定义是:
class IterRegistry(type):
def __iter__(cls):
return iter(cls._registry)
class Experiment(metaclass=IterRegistry):
_registry = []
counter = 0
def __init__(self, name, pathprotocol, protocol_struct, pathresult, wallA, wallB, wallC):
hashdat = fn.hashfile(pathresult)
hashpro = fn.hashfile(pathprotocol)
chk = fn.checkhash(hashdat)
if chk:
raise RuntimeError("The same experiment has already been added")
self._registry.append(self)
self.name = name
[...]
虽然fn.checkhash
是一个检查包含结果的文件的哈希值的函数:
def checkhash(hashdat):
for exp in cl.Experiment:
if exp.hashdat == hashdat:
return exp
return False
因此,如果我添加以前添加的实验,则不会被覆盖。
如果已经存在而不是引发错误,是否有可能以某种方式返回现有实例? (我知道__init__
阻止它是不可能的)
答案 0 :(得分:1)
尝试这样做(非常简化的例子):
class A:
registry = {}
def __init__(self, x):
self.x = x
@classmethod
def create_item(cls, x):
try:
return cls.registry[x]
except KeyError:
new_item = cls(x)
cls.registry[x] = new_item
return new_item
A.create_item(1)
A.create_item(2)
A.create_item(2) # doesn't add new item, but returns already existing one
答案 1 :(得分:1)
如果要自定义创建而不是仅在新创建的对象中初始化,则可以使用__new__
:
class Experiment(metaclass=IterRegistry):
_registry = []
counter = 0
def __new__(cls, name, pathprotocol, protocol_struct, pathresult, wallA, wallB, wallC):
hashdat = fn.hashfile(pathresult)
hashpro = fn.hashfile(pathprotocol)
chk = fn.checkhash(hashdat)
if chk: # already added, just return previous instance
return chk
self = object.__new__(cls) # create a new uninitialized instance
self._registry.append(self) # register and initialize it
self.name = name
[...]
return self # return the new registered instance