Seite 1 von 1

Python Singleton aus dem Kochbuch

Verfasst: Sonntag 19. März 2006, 11:11
von Mad-Marty
Hallo,

das Singleton Rezept aus dem Kochbuch funktioniert nicht.

Was ist da falsch ?

Code: Alles auswählen

>>> class Singleton(object):
... 	def __new__(cls, *args, **kwargs):
... 		if '_inst' not in vars(cls):
... 			cls._inst = type.__new__(cls, *args, **kwargs)
... 	        return cls._inst
... 	       
>>> class mycls (Singleton):
... 	pass
... 
>>> a=mycls()
Traceback (most recent call last):
  File "<interactive input>", line 1, in ?
  File "<interactive input>", line 4, in __new__
TypeError: type.__new__(mycls): mycls is not a subtype of type

Verfasst: Sonntag 19. März 2006, 11:23
von modelnine
Anstelle von type.__new__ brauchts einfach nur ein object.__new__...

Ahso, und ich weiß nicht ob er meckert weil Du *args und **kwargs mitgibst. Ich würd einfach object.__new__(cls) machen, anstelle von type.__new__(cls,*args,**kwargs).

Verfasst: Sonntag 19. März 2006, 11:49
von Mad-Marty
modelnine hat geschrieben:Anstelle von type.__new__ brauchts einfach nur ein object.__new__...

Ahso, und ich weiß nicht ob er meckert weil Du *args und **kwargs mitgibst. Ich würd einfach object.__new__(cls) machen, anstelle von type.__new__(cls,*args,**kwargs).

Danke Heiko, hast recht, object.__new__ hilft.

Da hätt ich aber auch mal hinschauen können :-/ :roll:

Hatte nicht erwartet das im Cookbook ein fehler ist, deswegen hab ich erst gedacht falsche python version.

Verfasst: Sonntag 19. März 2006, 13:26
von Mad-Marty
So, jetzt möchte ich das ganze mal mit metaclassen probieren.

Allerdings mit sehr mässigen erfolg :-(


Habe das da unten verbrochen, und auch viele andere versionen - keine geht.

Kann mir bitte jemand sagen was ich falsch mache ?

Code: Alles auswählen

class MetaSingleton(type):
    # __new__ gets the metaclass as first arg
    #def __new__(mcl, *args, **kwargs):

    # __init__ gets the produced class as first arg
    def __init__(cls, *args, **kwargs):
        
        def singleton_new(cls, *args, **kwargs):
            if '_inst' not in vars(cls):
                cls._inst = object.__new__(cls, *args, **kwargs)
            return cls._inst
        
        cls.__new__ = singleton_new


def TestMetaSingleton():
    class Foo(object):
        __metaclass__ = MetaSingleton

    a = Foo()
    b = Foo()
    print a,b

TestMetaSingleton()

Verfasst: Sonntag 19. März 2006, 13:35
von modelnine

Code: Alles auswählen

class MetaSingleton(type):
    # __new__ gets the metaclass as first arg
    #def __new__(mcl, *args, **kwargs):

    # __init__ gets the produced class as first arg
    def __init__(cls, *args, **kwargs):
        
        def singleton_new(cls, *args, **kwargs):
            if '_inst' not in vars(cls):
                cls._inst = object.__new__(cls, *args, **kwargs)
            return cls._inst
        
        cls.__new__ = staticmethod(singleton_new)


def TestMetaSingleton():
    class Foo(object):
        __metaclass__ = MetaSingleton

    a = Foo()
    b = Foo()
    print a,b

TestMetaSingleton()
Der Code sollte gehen (das ist untertrieben, der Code geht ;-))... Ist aber nicht umbedingt eine Paradeanwendung für Metaklassen... ;-)

Verfasst: Mittwoch 22. März 2006, 08:55
von helmut
Hier findet man die Auflistung der bekannten Druckfehler und die jeweils neue Version. Im vorliegenden Fall:

Code: Alles auswählen

# [Seite 271]  second line of code from the bottom;
cls._inst = type.__new__(cls, *args, **kwargs)

# NOW READS:
cls._inst = super(Singleton, cls).__new__(cls, *args, **kwargs)
Helmut