كيفية إنشاء فئة لا إعادة إنشاء كائن متطابقة مع معلمات الإدخال

StackOverflow https://stackoverflow.com/questions/669932

  •  21-08-2019
  •  | 
  •  

سؤال

أنا أحاول إنشاء فئة لا إعادة إنشاء كائن مع نفس معلمات الإدخال.عند محاولة إنشاء مثيل فئة مع نفس المعلمات التي تم استخدامها لإنشاء القائمة بالفعل كائن ، أنا فقط أريد فئة جديدة للعودة مؤشر إنشاؤها بالفعل (كلفة إنشاء) الكائن.هذا هو ما كنت قد حاولت حتى الآن:

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
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top