当前位置:  开发笔记 > 编程语言 > 正文

如何创建不重新创建具有相同输入参数的对象的类

如何解决《如何创建不重新创建具有相同输入参数的对象的类》经验,为你挑选了2个好方法。

我试图创建一个不重新创建具有相同输入参数的对象的类.当我尝试使用与创建已存在对象相同的参数来实例化一个类时,我只希望我的新类返回一个指向已经创建的(昂贵创建的)对象的指针.这是我到目前为止所尝试的:

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__,我确信我不会以正确的方式解决这个问题.请让我直截了当.



1> Jerry Neuman..:

这是一个类装饰器,使类成为多个:

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

现在,如果使用相同的id实例化MyObject,则会获得相同的实例:

a = MyObject(1)
b = MyObject(2)
c = MyObject(2)

a is b  # False
b is c  # True



2> S.Lott..:

首先,在Python中使用大写字母类名称.

其次,使用Factory设计模式来解决这个问题.

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]

这比使用新的具有类级别对象池的方式简单得多.


使用`__new__`确实是/一种pythonic方式,而不是引入另一个类 - 你的解决方案是惯用的Java.另外,不要在括号内插入空格,也不要在Python中使用camelCase方法名.
推荐阅读
依然-狠幸福
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有