Python Singleton aus dem Kochbuch

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Mad-Marty
User
Beiträge: 317
Registriert: Mittwoch 18. Januar 2006, 19:46

Sonntag 19. März 2006, 11:11

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
modelnine
User
Beiträge: 670
Registriert: Sonntag 15. Januar 2006, 18:42
Wohnort: Celle
Kontaktdaten:

Sonntag 19. März 2006, 11:23

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).
--- Heiko.
Mad-Marty
User
Beiträge: 317
Registriert: Mittwoch 18. Januar 2006, 19:46

Sonntag 19. März 2006, 11:49

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.
Mad-Marty
User
Beiträge: 317
Registriert: Mittwoch 18. Januar 2006, 19:46

Sonntag 19. März 2006, 13:26

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()
modelnine
User
Beiträge: 670
Registriert: Sonntag 15. Januar 2006, 18:42
Wohnort: Celle
Kontaktdaten:

Sonntag 19. März 2006, 13:35

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... ;-)
--- Heiko.
helmut
User
Beiträge: 57
Registriert: Mittwoch 2. November 2005, 07:45
Wohnort: Dormagen

Mittwoch 22. März 2006, 08:55

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
Antworten