Return class instance instead of creating a new one if already existing
我为我正在进行的一些实验室实验的结果定义了一个名为
我的班级定义是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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 [...] |
虽然
1 2 3 4 5 | def checkhash(hashdat): for exp in cl.Experiment: if exp.hashdat == hashdat: return exp return False |
这样,如果我添加一个以前添加的实验,这将不会被覆盖。
如果已经存在,是否可以以某种方式返回现有实例,而不是引发错误?(我知道在
如果要自定义创建而不只是在新创建的对象中初始化,则可以使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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 |
试着这样做(非常简单的例子):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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 |