2009-10-19 4 views
5

Ho un Monostate di base con Python 2.6.Avvertimenti di deprecazione di Python con Monostate __new__ - Qualcuno può spiegare perché?

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

che fortunatamente mi dà il seguente avviso Deprecation ..

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

Dopo un po 'di googling ho trovato questo è attaccato Bug #1683368. Quello che non riesco a capire è cosa significhi. Si lamenta della seguente riga

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

Che sembra essere OK. Qualcuno può spiegare in laici termini perché questo è un problema. Capisco che "questo è incoerente con altri built-in, come l'elenco", ma non sono sicuro di aver capito perché. Qualcuno potrebbe spiegare questo mi mostra il modo giusto per farlo?

Grazie

risposta

1

L'allarme arriva dal fatto che __new__() può avere argomenti, ma dato che sono ignorati in tutto il mondo, passando args (diverso da CLS) ad esso causa l'avviso. In realtà non è (attualmente) un errore passare gli argomenti aggiuntivi, ma non hanno alcun effetto.

In py3k diventerà un errore passare gli arg.

+0

sto riuscendo a vedere come sono ignorati? Elimina * args e ** kwargs dal nuovo e bombarderà perché sono necessari per __init__ che li sta aspettando. L'ultima frase è quella che sto cercando di prevenire :-) Voglio che funzioni in 3k. – rh0dium

+0

Non posso discutere con i progettisti di linguaggi. Se dicono "nuovo non prende argomenti", lo faccio prendere argomenti. '__init__' e' __new__' funzionano allo stesso modo, forse il tuo caso d'uso dovrebbe usare init invece di new. –

6

Vedi python-singleton-object-instantiation, e nota Alex Martelli's Singleton esempio:

class Singleton(object): 

    __instance = None 

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

La domanda __new__ deprecation era answered by Guido:

Il messaggio significa proprio quello che dice. :-) Non ha senso chiamare oggetto .__ nuovo __() con più di un parametro di classe, e qualsiasi codice che facesse era semplicemente scaricare quegli arg in un buco nero.

L'unico momento in cui ha senso per oggetto .__ nuova __() per ignorare aggiuntivi argomenti è quando non viene sovrascritto, ma __init__ è essere sovrascritto - allora avete un __new__ completamente predefinito e il controllo degli argomenti del costruttore è relegato a __init__.

Lo scopo di tutto questo è di rilevare l'errore in una chiamata come oggetto (42) che passa (di nuovo) un argomento che non viene utilizzato. Questo è spesso un sintomo di un bug nel programma.

--Guido

+0

Questo è un singleton (aka highlander) non è un borg (monostatico). Sono stato [istruito] [1] su quello già.Ho anche i commenti di Guido pronti, ma come ho detto prima se il tuo init ha i requisiti di * args ** kwargs allora anche __new__ li richiederebbe? Destra?? [1]: http://stackoverflow.com/questions/1575680/assicurazione-che-una-una-stanza-di-una-class-rights-run – rh0dium

+0

Scusa il grassetto e il collegamento è stato incasinato .. – rh0dium

+0

Guido dice esplicitamente che è necessario solo __init__ per verificare gli argomenti del costruttore. – gimel

Problemi correlati