2009-10-19 6 views
5

Tengo un Monostate básico con Python 2.6.Advertencias de destrucción de Python con Monostate __new__ - ¿Alguien puede explicar por qué?

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

Qué feliz me da la siguiente advertencia Deprecation ..

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

Después de un poco de google Encuentro esto está unido a Bug #1683368. Lo que no puedo entender es lo que esto significa. Se queja de la siguiente línea

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

Lo que parece estar bien. ¿Alguien puede explicar en laymens términos por qué esto es un problema. Entiendo que "esto es inconsistente con otros complementos, como la lista", pero no estoy seguro de entender por qué. ¿Alguien me explicaría esto y me mostraría la forma correcta de hacerlo?

Gracias

Respuesta

1

La advertencia viene del hecho de que __new__() puede tener argumentos, pero dado que son ignorados por todos lados, pasando args (que no sea CLS) a causa de la advertencia. En realidad, no es (actualmente) un error pasar las args extra, pero no tienen ningún efecto.

En py3k se convertirá en un error pasar las args.

+0

estoy fallando para ver cómo se ignoran? Elimina * args y ** kwargs de nuevo y bombardeará porque __init__ los necesita. Tu última declaración es la que intento evitar :-) Quiero que funcione en 3k. – rh0dium

+0

No puedo discutir con los diseñadores de idiomas. Si dicen "nuevo no toma ningún argumento", lo hago sin argumentos. '__init__' y' __new__' funcionan de forma similar, tal vez su caso de uso debería usar init en lugar de new. –

6

Ver python-singleton-object-instantiation y observe Alex Martelli's ejemplo Singleton:

class Singleton(object): 

    __instance = None 

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

La pregunta era __new__ deprecationanswered by Guido:

significa que el mensaje sólo lo que dice. :-) No tiene sentido llamar al objeto .__ nuevo __() con más de un parámetro de clase, y cualquier código que hizo fue simplemente dejar esos argumentos en un agujero negro.

El único momento en el que tiene sentido para el objeto .__ nueva __() para ignorar adicionales argumentos es cuando no está siendo anulado, pero __init__ es siendo anulado - entonces usted tiene un __new__ completamente defecto y la comprobación de los argumentos del constructor se relega a __init__.

El propósito de todo esto es detectar el error en una llamada como objeto (42) que (nuevamente) pasa un argumento que no se utiliza. Esto es a menudo un síntoma de un error en su programa.

--Guido

+0

Eso es un singleton (también conocido como highlander) no es un borg (monostate). Ya fui [educado] [1] sobre eso.También tengo listos los comentarios de Guido, pero como dije antes, si tu init tiene los requisitos de * args ** kwargs entonces __new__ también los necesitaría? ¿¿Derecha?? [1]: http://stackoverflow.com/questions/1575680/ensure-that-only-one-instance-of-a-class-gets-run – rh0dium

+0

Lo sentimos, el enlace en negrita se echó a perder .. – rh0dium

+0

Guido explícitamente dice que solo __init__ es requerido para verificar los argumentos del constructor. – gimel

Cuestiones relacionadas