2015-10-09 3 views
5

seguito è il metodo __init__ della classe Local dalla libreria werkzeug:`oggetto .__ setattr __ (self, ..., ...)` invece di `setattr (self, ..., ...)`?

def __init__(self): 
    object.__setattr__(self, '__storage__', {}) 
    object.__setattr__(self, '__ident_func__', get_ident) 

Non capisco due cose su questo codice:

  1. Perché hanno scritto

    object.__setattr__(self, '__storage__', {}) 
    

    anziché semplicemente

    `setattr(self, '__storage__', {})` 
    
  2. Perché hanno anche utilizzare __setattr__ se la potrebbe semplicemente scrivere

    self.__storage__ = {} 
    

risposta

6

Ciò garantisce che venga utilizzata la definizione Python predefinita di __setattr__. Viene generalmente utilizzato se la classe ha sostituito __setattr__ per eseguire un comportamento non standard, ma si desidera comunque accedere al comportamento originale __setattr__.

Nel caso di Werkzeug, se si guarda alla classe Local vedrete __setattr__ si definisce in questo modo:

def __setattr__(self, name, value): 
    ident = self.__ident_func__() 
    storage = self.__storage__ 
    try: 
     storage[ident][name] = value 
    except KeyError: 
     storage[ident] = {name: value} 

Invece di impostare attributi nel dizionario dell'oggetto, li imposta in Dizionario __storage__ inizializzato in precedenza. Per impostare l'attributo __storage__ (in modo che sia possibile accedervi come self.__storage__ in seguito), è necessario utilizzare la definizione originale di __setattr__ dall'oggetto, motivo per cui la notazione awkward viene utilizzata nel costruttore.

+1

Aggiungo solo che sebbene sembri scomodo nella fonte, fornisce un'interfaccia piacevole per gli utenti della classe. –

1

Perché la stessa classe definisce __setattr__ e questo deve ignorare che, dal momento che la prima riga dice self.__ident_func__() che non avrebbe lavoro ancora.

2

Vogliono utilizzare esplicitamente l'implementazione di base object.__setattr__ anziché un metodo di istanza del metodo eventualmente sovrascritto da qualche altra parte nella catena di ereditarietà. Local implementa il proprio __setattr__ in modo da evitare questo.