2010-06-25 33 views
12

He la clase siguiente:Python, tipos de subclases inmutables

class MySet(set): 

    def __init__(self, arg=None): 
     if isinstance(arg, basestring): 
      arg = arg.split() 
     set.__init__(self, arg) 

Esto funciona como se esperaba (inicializar el sistema con las palabras de la cadena en lugar de las letras). Sin embargo, cuando quiero hacer lo mismo con la versión inmutable de conjunto, el método __init__ parece ser ignorado:

class MySet(frozenset): 

    def __init__(self, arg=None): 
     if isinstance(arg, basestring): 
      arg = arg.split() 
     frozenset.__init__(self, arg) 

puedo lograr algo similar con __new__?

+1

Creo que la razón de que '__new __ (..)' toma la iniciativa cuando se trata de esculpir instancias de tipos inmutables es aprovechar la inmutabilidad y reservar una oportunidad para devolver una instancia existente, si está disponible. (Pero si uno no quiere esa ventaja, entonces podría hacer un tipo inmutable sin jugar con '__new__ (..)'. En particular, '__nuevo __ (..)' no ofrece ningún contexto especial. tiene que modificar los campos inmutables a través de 'object .__ setattr __ (..)' o similar, ya sea dentro de '__new __ (..)' o '__init _ (..)'.) –

Respuesta

12

Sí, es necesario anular __new__ método especial:

class MySet(frozenset): 

    def __new__(cls, *args): 
     if args and isinstance (args[0], basestring): 
      args = (args[0].split(),) + args[1:] 
     return super (MySet, cls).__new__(cls, *args) 

print MySet ('foo bar baz') 

y la salida es:

MySet(['baz', 'foo', 'bar']) 
+0

super! puede __init__ estar en desuso? – EoghanM

+4

@EoghanM: No, '__new__' es diferente. Básicamente, '__new__' crea * o * búsquedas una instancia, mientras que' __init__' configura una instancia ya creada. Las principales razones para anular '__new__' es evitar la creación de una nueva instancia (por ejemplo, hacer que 'SomeType()' siempre devuelva el mismo objeto singleton), o subclase de ciertos tipos inmutables, como' frozenset'. Consulte http://docs.python.org/reference/datamodel.html#special-method-names para obtener más información. – doublep

+0

thx - mi pregunta secundaria se plantea con mayor claridad aquí: http://stackoverflow.com/questions/3131488/ – EoghanM

Cuestiones relacionadas