Haw = singularize(Haw) haw = Haw(1,2L,3.5,s =''string'',more =''example'') print vars(haw) print vars(Haw(111,a =''222'')) print [Haw(),Haw()] 打印[Haw()。args [i] for x in xrange(len(Haw()。args))] print [Haw()。kw [' 's''],Haw()。kw [''more'']] 如果__name__ ==''__ main__'': test() -------------------------------------------- ----------------------- 无保证,介意;-) 输出,显示单个实例,不重复初始化: < class''__ main __。Foobar''> [< __ main __。Foobar对象at 0x02F03BEC>,< __ main __。位于0x02F03BEC的Foobar对象>] < __ main __。位于0x02F03DCC的Boobar对象> 123 < class''__ main __。Boobar''> [< __ main __。在0x02F03DCC处的Boobar对象>,< __ main __。在0x02F03DCC处的Boobar对象>] [123,123] < class''__ main __。Gee''> Gee:< __ main __。Gee对象at 0x02F03E8C> [< __ main __。位于0x02F03E8C的Gee对象>,< __ main __。位于0x02F03E8C的Gee对象>] {''args'':( 1,2L ,3.5),''kw'':{''s'':''string'',''more'':''example''}} {''args'' :(1,2L,3.5),''kw'':{''s'':''string'',''more'':''example''}} [ < __ main __。Haw对象位于0x02F03F0C>,< __ main __。Haw对象位于0x02F03F0C>] [1,2L,3.5] [''string'', ''示例''] 问候, Bengt Richter 我从来没想过或者需要一个单件对象让我感到震惊。 你介意分享吗?你的用例?我很好奇。 谢谢, STeVe Hi, I''ve been looking into ways of creating singleton objects. With Python2.3 Iusually used a module-level variable and a factory function to implementsingleton objects. With Python2.4 I was looking into decorators. The examples from PEP 318 http://www.python.org/peps/pep-0318.html#examples don''t work - AFAIK because:- you cannot decorate class definitions (why was it left out?)- __init__ must return NoneHowever, you can use the decorator: def singleton(f):instances = {}def new_f(*args, **kwargs):if (f not in instances):instances[f] = f(*args, **kwargs)return instances[f]new_f.func_name = f.func_namenew_f.func_doc = f.func_docreturn new_f with a class that overwrites the __new__ methof of new-style classes: class Foobar(object):def __init__(self):print self @singletondef __new__(self):return object.__new__(Foobar)Is this particularly ugly or bad? Thanks for comments,CiaoUwe 解决方案 Seems a little confoluted. Why can''t you just use something like: class Singleton(object):def __new__(cls, *args, **kwargs):try:return cls.__instance__except AttributeError:instance = cls.__instance__ = super(Singleton, cls).__new__(cls, *args, **kwargs)return instance class Foobar(Singleton):def __init__(self):print self ? STeVe I thought of a different approach. The singleton function heretakes arguments for the initial instance of a class, and instantiates it,and then modifies the class''s __new__ and __init__ to return the initialinstance and prevent further initialization. Used directly, as normal function decorators can be (i.e., fun = deco(fun)or fun = deco(args)(fun)), singleton works (not counting bugs ;-) as is. To invoke it as decorator demands a trick workaround using an intermediateworkaround decorator and a dummy funcion definition synonymous with theclass to be decorated (which mus pre-exist for this). BTW, this is different from the class-decorator-as-sugar-for-metaclass,(which I suggested previously) since it take one class argument vs argumentsfor the metaclass __new__ etc.I added a singularize decorator for when you don''t immediately want tospecify the first initiazization parameters, but want the first instanceto to become the singleton instance whenever that happens later. So here''s some hacks to play with: ----< singleton.py >-----------------------------------------------def singleton(*args, **kw):"""decorator cacheing singleton instance immediately"""def singdeco(cls):assert isinstance(cls, type)inst = cls(*args, **kw)cls.__new__ = staticmethod(lambda *a, **kw: inst)cls.__init__ = staticmethod(lambda *a, **kw: None) # no re-initreturn clsreturn singdeco import sysdef workaround(f):cls = sys._getframe(1).f_locals.get(f.func_name)if cls is None:cls = sys._getframe(1).f_globals.get(f.func_name)return cls def singularize(cls):"""decorator setting singleton-making mousetrap"""oldnew = cls.__new__def __new__(cls, *args, **kw):inst = oldnew(cls)inst.__init__(*args, **kw)cls.__new__ = staticmethod(lambda *a,**kw: inst)cls.__init__ = staticmethod(lambda *a, **kw: None)return instcls.__new__ = staticmethod(__new__)return cls def test():class Foobar(object): passFoobar = singleton()(Foobar)print Foobarprint [Foobar() for x in xrange(2)] class Boobar(object):def __init__(self, v):print self, vself.v = v@singleton(123)@workarounddef Boobar(): pass # dummy used by workaround for name print Boobarprint [Boobar(x) for x in xrange(2)]print [Boobar(x).v for x in xrange(2)] class Gee(object):def __init__(self): print ''Gee:'', self Gee = singularize(Gee)print Geeprint [Gee() for x in xrange(2)] class Haw(object):def __init__(self, *args, **kw):self.args = argsself.kw =kw Haw = singularize(Haw)haw = Haw(1,2L, 3.5, s=''string'', more=''example'')print vars(haw)print vars(Haw(111, a=''222''))print [Haw(), Haw()]print [Haw().args[i] for i in xrange(len(Haw().args))]print [Haw().kw[''s''], Haw().kw[''more'']]if __name__ == ''__main__'':test()-------------------------------------------------------------------No guarantees, mind ;-) Output, showing single instances and no repeat initialization: <class ''__main__.Foobar''>[<__main__.Foobar object at 0x02F03BEC>, <__main__.Foobar object at 0x02F03BEC>]<__main__.Boobar object at 0x02F03DCC> 123<class ''__main__.Boobar''>[<__main__.Boobar object at 0x02F03DCC>, <__main__.Boobar object at 0x02F03DCC>][123, 123]<class ''__main__.Gee''>Gee: <__main__.Gee object at 0x02F03E8C>[<__main__.Gee object at 0x02F03E8C>, <__main__.Gee object at 0x02F03E8C>]{''args'': (1, 2L, 3.5), ''kw'': {''s'': ''string'', ''more'': ''example''}}{''args'': (1, 2L, 3.5), ''kw'': {''s'': ''string'', ''more'': ''example''}}[<__main__.Haw object at 0x02F03F0C>, <__main__.Haw object at 0x02F03F0C>][1, 2L, 3.5][''string'', ''example''] Regards,Bengt Richter It strikes me that I''ve never wanted or needed a singleton object.Would you mind sharing your use case? I''m just curious. Thanks, STeVe 这篇关于单例对象与装饰器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 09-22 08:34