题
我试图创建一个类,不重新创建具有相同的输入参数的对象。当我尝试实例与被用来创建一个已经存在的对象相同的参数类,我只是希望我的新类的指针返回到已创建(昂贵创建)对象。这是我到目前为止已经试过:
class myobject0(object):
# At first, I didn't realize that even already-instantiated
# objects had their __init__ called again
instances = {}
def __new__(cls,x):
if x not in cls.instances.keys():
cls.instances[x] = object.__new__(cls,x)
return cls.instances[x]
def __init__(self,x):
print 'doing something expensive'
class myobject1(object):
# I tried to override the existing object's __init__
# but it didnt work.
instances = {}
def __new__(cls,x):
if x not in cls.instances.keys():
cls.instances[x] = object.__new__(cls,x)
else:
cls.instances[x].__init__ = lambda x: None
return cls.instances[x]
def __init__(self,x):
print 'doing something expensive'
class myobject2(object):
# does what I want but is ugly
instances = {}
def __new__(cls,x):
if x not in cls.instances.keys():
cls.instances[x] = object.__new__(cls,x)
cls.instances[x]._is_new = 1
else:
cls.instances[x]._is_new = 0
return cls.instances[x]
def __init__(self,x):
if self._is_new:
print 'doing something expensive'
这是我的第一次创业到压倒一切的__new__
,我相信我不会去它的正确途径。设置我直,请。
解决方案
首先,使用大写类名称在Python。
其次,使用的厂强>设计模式来解决这个问题。
class MyObject( object ):
def __init__( self, args ):
pass # Something Expensive
class MyObjectFactory( object ):
def __init__( self ):
self.pool = {}
def makeMyObject( self, args ):
if args not in self.pool:
self.pool[args] = MyObject( args )
return self.pool[args]
这比鬼混使用对象的新的,具有一流水平池简单得多。
其他提示
这里的一个类装饰使一个类一个多例:
def multiton(cls):
instances = {}
def getinstance(id):
if id not in instances:
instances[id] = cls(id)
return instances[id]
return getinstance
(这是从PEP 318单身装饰的轻微变体。)
然后,让你的类多例,使用装饰:
@multiton
class MyObject( object ):
def __init__( self, arg):
self.id = arg
# other expensive stuff
现在,如果实例MyObject来使用相同的ID,你会得到相同的实例:
a = MyObject(1)
b = MyObject(2)
c = MyObject(2)
a is b # False
b is c # True
不隶属于 StackOverflow