2009-10-19 9 views
5

Mam podstawowy Monostate z Pythonem 2.6.Python Deprecation Ostrzeżenia z Monostate __new__ - Czy ktoś może wyjaśnić, dlaczego?

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",) 

które szczęśliwie daje mi następujące ostrzeżenie Deprecation ..

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

Po trochę googlowania znajdę ten jest dołączony do Bug #1683368. Nie mogę zrozumieć, co to oznacza. Narzeka na następującą linię:

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

Co wydaje się być OK. Czy ktoś może wyjaśnić, dlaczego to jest problem? Rozumiem, że "jest to niezgodne z innymi wbudowanymi, takimi jak lista", ale nie jestem pewien, czy rozumiem dlaczego. Czy ktoś wytłumaczyłby mi to, pokazując mi właściwą drogę?

Dzięki

Odpowiedz

1

Ostrzeżenie pochodzi z faktu, że __new__() może mieć argumenty, ale ponieważ są one ignorowane wszędzie, przechodząc args (inne niż CLS) i to powoduje, że ostrzeżenia. Nie jest to (obecnie) błąd przekazywania dodatkowych argumentów, ale nie mają one żadnego efektu.

W py3k stanie się błędem do przekazania argumentów.

+0

jestem braku zobaczyć, jak są one ignorowane? Wyjmij * args i ** kwargs z nowego, a on zbombarduje, ponieważ są potrzebne __init__, który ich oczekuje. Ostatnie oświadczenie jest tym, które próbuję zapobiec :-) Chcę, żeby działało w 3k. – rh0dium

+0

Nie mogę dyskutować z projektantami języków. Jeśli powiedzą "nowy nie bierze żadnych argumentów", to nie chcę argumentować. '__init__' i' __new__' działają podobnie, być może twój przypadek użycia powinien używać init zamiast new. –

6

Zobacz python-singleton-object-instantiation i zauważ Alex Martelli's singleton przykład:

class Singleton(object): 

    __instance = None 

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

__new__ deprecation pytanie answered by Guido:

komunikat oznacza tylko to, co ona mówi. :-) Nie ma sensu dzwonić pod obiekt .__ nowy __() z więcej niż jednym parametrem klasy, a każdy kod, który zrobił , po prostu zrzucał te argumenty do czarnej dziury.

Jedyny czas, kiedy ma to sens dla obiektu .__ nowego __(), aby zignorować dodatkowe argumentów jest, gdy to nie jest przesłonięta, ale __init__ jest jest nadpisane - to masz całkowicie domyślną __new__ i sprawdzanie Argumenty konstruktora są relegowane do __init__.

Celem tego wszystkiego jest złapanie błędu w wywołaniu takim jak obiekt (42), który (ponownie) przekazuje argument, który nie jest używany. Jest to często symptom błędu w twoim programie.

--Guido

+0

To singleton (aka góral) nie jest borgiem (monostatem). Byłem już [szkolony] [1] na ten temat.Mam również gotowe komentarze Guido, ale jak już powiedziałem wcześniej, jeśli twój init ma wymagania * args ** kwargs, to __new__ też ich wymaga? Dobrze?? [1]: http://stackoverflow.com/questions/1575680/ensure-that-only-one-instance--class-gets-run – rh0dium

+0

Przepraszamy, pogrubienie i link zostały pomieszane .. – rh0dium

+0

Guido wyraźnie mówi, że tylko __init__ jest wymagany do sprawdzenia argumentów konstruktora. – gimel

Powiązane problemy