2010-06-25 20 views
12

Sono la seguente classe:Python, tipi sottoclasse immutabili

class MySet(set): 

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

Questo funziona come previsto (inizializzazione del set con le parole della stringa piuttosto che le lettere). Tuttavia quando voglio fare lo stesso con la versione immutabile di set, il metodo __init__ sembra essere ignorato:

class MySet(frozenset): 

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

Posso realizzare qualcosa di simile con __new__?

+1

Penso che il motivo per cui '__new __ (..)' prende l'iniziativa quando si tratta scolpire istanze di tipi immutabili è sfruttare l'immutabilità e riservare l'opportunità di restituire un'istanza esistente, se disponibile. (Ma se uno non vuole quel vantaggio, allora potrebbe fare un tipo immutabile senza scherzare con '__nuovo __ (..)'. In particolare, '__new __ (..)' non offre alcun contesto speciale. modificare i campi immutabili tramite 'oggetto .__ setattr __ (..)' o simile, sia che si trovi all'interno di '__nuovo __ (..)' o '__init _ (..)'.) –

risposta

12

Sì, è necessario eseguire l'override __new__ metodo speciale:

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') 

e l'uscita è:

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

super! può __init__ essere deprecato? – EoghanM

+4

@EoghanM: No, '__new__' è diverso. Fondamentalmente, '__new__' crea * o * cerca un'istanza, mentre' __init__' imposta un'istanza già creata. La ragione principale per sovrascrivere '__new__' è evitare la creazione di nuove istanze (ad esempio per fare in modo che' SomeType() 'restituisca sempre lo stesso oggetto singleton), o sottoclasse alcuni tipi immutabili, come' frozenset'. Vedi http://docs.python.org/reference/datamodel.html#special-method-names per i dettagli. – doublep

+0

thx - la mia domanda secondaria è più chiara qui: http://stackoverflow.com/questions/3131488/ – EoghanM

Problemi correlati