كيفية إنشاء فئة لا إعادة إنشاء كائن متطابقة مع معلمات الإدخال
سؤال
أنا أحاول إنشاء فئة لا إعادة إنشاء كائن مع نفس معلمات الإدخال.عند محاولة إنشاء مثيل فئة مع نفس المعلمات التي تم استخدامها لإنشاء القائمة بالفعل كائن ، أنا فقط أريد فئة جديدة للعودة مؤشر إنشاؤها بالفعل (كلفة إنشاء) الكائن.هذا هو ما كنت قد حاولت حتى الآن:
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__
و أنا مقتنع أنا لن أذهب عن ذلك بالطريقة الصحيحة.تعيين لي على التوالي ، من فضلك.
المحلول
أولا استخدم أسماء فئة في بيثون.
ثانيا استخدام مصنع تصميم نمط لحل هذه المشكلة.
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]
هذا هو أبسط بكثير من العبث مع وجود فئة مستوى برك من الكائنات.
نصائح أخرى
وهنا الديكور فئة لجعل فئة من multiton:
def multiton(cls):
instances = {}
def getinstance(id):
if id not in instances:
instances[id] = cls(id)
return instances[id]
return getinstance
(وهذا هو البديل طفيف في الديكور المفرد من PEP 318).
وبعد ذلك، لجعل صفك لmultiton، استخدم الديكور:
@multiton
class MyObject( object ):
def __init__( self, arg):
self.id = arg
# other expensive stuff
والآن، إذا كنت مثيل MyObject مع نفس الهوية، وتحصل على نفس المثال:
a = MyObject(1)
b = MyObject(2)
c = MyObject(2)
a is b # False
b is c # True