2009-10-19 10 views
5

Ich habe einen grundlegenden Monostate mit Python 2.6.Python Verfall Warnungen mit Monostate __new__ - Kann jemand erklären warum?

class Borg(object): 
    __shared_state = {} 
    def __new__(cls, *args, **kwargs): 
     self = object.__new__(cls, *args, **kwargs) 
     self.__dict__ = cls.__shared_state 
     return self 

    def __init__(self, *args, **kwargs): 
     noSend = kwargs.get("noSend", False) 
     reportLevel = kwargs.get("reportLevel", 30) 
     reportMethods = kwargs.get("reportMethods", "BaseReport") 
     contacts= kwargs.get("contacts", None) 

a = Borg(contacts="Foo", noSend="Bar",) 

Was mich glücklich die folgende Deprecation Warnung gibt ..

untitled:4: DeprecationWarning: object.__new__() takes no parameters 
    self = object.__new__(cls, *args, **kwargs) 

Nach ein bisschen googeln ich diese finden an Bug #1683368 angebracht. Was ich nicht herausfinden kann, ist, was das bedeutet. Es beschwert sich über die folgende Zeile

self = object.__new__(cls, *args, **kwargs) 

Die scheint in Ordnung zu sein. Kann jemand in Laien Begriffe erklären, warum dies ein Problem ist. Ich verstehe, dass "dies inkonsistent ist mit anderen eingebauten, wie Liste", aber ich bin mir nicht sicher, warum ich verstehe. Würde mir jemand erklären, dass das der richtige Weg ist?

Dank

Antwort

1

Die Warnung kommt von der Tatsache, dass __new__() args haben kann, aber da sie überall ignoriert sind, vorbei an args (außer cls), um es die Warnung verursacht. Es ist eigentlich (momentan) kein Fehler, die zusätzlichen Argumente zu übergeben, aber sie haben keine Wirkung.

In py3k wird es ein Fehler, die Argumente zu übergeben.

+0

ich Fehler zu sehen, wie sie ignoriert werden? Nimm * args und ** kwargs von new heraus und es wird bombardieren, weil sie von __init__ benötigt werden, was sie erwartet. Sie letzte Aussage ist die, die ich verhindern will :-) Ich will es in 3k arbeiten. – rh0dium

+0

Ich kann nicht mit den Sprachdesignern streiten. Wenn sie sagen "Neues braucht keine Argumente", lasse ich es keine Argumente nehmen. '__init__' und' __new__' funktionieren ähnlich, vielleicht sollte Ihr Anwendungsfall init anstelle von new sein. –

6

Siehe python-singleton-object-instantiation, und beachten Sie Alex Martelli's Singletons Beispiel:

class Singleton(object): 

    __instance = None 

    def __new__(cls): 
     if cls.__instance == None: 
      __instance = type.__new__(cls) 
      __instance.name = "The one" 
     return __instance 

Die __new__ deprecation Frage answered by Guido war:

Die Nachricht bedeutet nur, was es sagt. :-) Es hat keinen Sinn, object .__ new __() mit mehr als einem Klassenparameter aufzurufen, und jeder Code, der tat, warf diese Argumente in ein schwarzes Loch.

Das einzige Mal, wenn es sinnvoll, für die Objekt .__ neue __() ignorieren zusätzliche Argumente macht, ist, wenn es nicht außer Kraft gesetzt werden, aber __init__ ist außer Kraft gesetzt werden - dann haben Sie eine völlig Standard __new__ und die Prüfung von Konstruktorargumenten wird auf __init__ verwiesen.

Der Zweck all dies ist, um den Fehler in einem Anruf wie Objekt (42) zu fangen, die (erneut) ein Argument übergeben, das nicht verwendet wird. Dies ist oft ein Symptom für einen Fehler in Ihrem Programm.

--Guido

+0

Das ist ein Singleton (alias Highlander) ist kein Borg (Monostate). Ich bin bereits darauf [geschult] [1].Ich habe auch Guido's Kommentare fertig, aber wie ich schon sagte, wenn Ihr init die Anforderungen von * args ** kwargs hat, würde __new__ sie auch benötigen? Recht?? [1]: http://stackoverflow.com/questions/1575680/ensure-that-only-one-instance-of-a-class-gets-run – rh0dium

+0

Sorry das Fett und Link wurde vermasselt .. – rh0dium

+0

Guido sagt explizit, dass nur __init__ benötigt wird, um Konstruktorargumente zu überprüfen. – gimel

Verwandte Themen