2009-10-06 9 views
6

Io uso "proprietà" per garantire che le modifiche alle variabili di istanza di un oggetto siano incluse nei metodi in cui è necessario.Variabili di istanze costanti?

Che dire quando un'istanza ha una variabile che non dovrebbe essere modificata logicamente? Ad esempio, se sto creando una classe per un processo, ogni istanza di Processo dovrebbe avere un attributo pid a cui si accede frequentemente, ma che non dovrebbe essere modificato.

Qual è il modo più Python per gestire qualcuno che tenti di modificare tale variabile di istanza?

  • sufficiente fiducia l'utente non per cercare di cambiare qualcosa che non dovrebbero?

  • Utilizzare la proprietà ma generare un'eccezione se la variabile di istanza è modificata?

  • Qualcos'altro?

+0

http://stackoverflow.com/questions/1358711/raising-an-exception-on-updating-a-constant-attribute-in-python –

risposta

6

nome Prepend della variabile con __, e creare proprietà di sola lettura, Python si prenderà cura di eccezioni, e variabile stessa saranno protetti dalla sovrascrittura accidentale.

class foo(object): 
    def __init__(self, bar): 
     self.__bar = bar 

    @property 
    def bar(self): 
     return self.__bar 

f = foo('bar') 
f.bar   # => bar 
f.bar = 'baz' # AttributeError; would have to use f._foo__bar 
+0

Nelle ultime due righe, si intende "f.foo" e "f .foo = 'baz' ", giusto? –

+0

Sì, ho confuso i nomi delle variabili. Già corretto –

+1

Trovo che gli attributi "privati" del nome siano più problematici di quanto valgano. Un singolo trattino basso renderà più semplice la sottoclassi mentre continua a comunicare "non toccare questo" agli utenti. –

1

Forse è possibile ignorare __setattr__? Nella linea di,

def __setattr__(self, name, value): 
    if self.__dict__.has_key(name): 
     raise TypeError, 'value is read only' 
    self.__dict__[name] = value 
3

La semplice fiducia nell'utente non è necessariamente una cosa negativa; se stai solo scrivendo un rapido programma Python da utilizzare una volta e gettato via, potresti benissimo fidarti che l'utente non altera il campo pid.

IMHO il modo più Python per applicare il campo di sola lettura consiste nell'utilizzare una proprietà che solleva un'eccezione nel tentativo di impostare il campo.

Quindi, IMHO hai un buon istinto su questa roba.

1

Utilizzare semplicemente una proprietà e un attributo nascosto (con prefisso uno).

Le proprietà semplici sono di sola lettura!

>>> class Test (object): 
... @property 
... def bar(self): 
... return self._bar 
... 
>>> t = Test() 
>>> t._bar = 2 
>>> t.bar 
2 
>>> t.bar = 2 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: can't set attribute 

Nascondere con doppia sottolineatura non viene utilizzato per nascondere l'implementazione, ma per essere sicuri di non collidono con una sottoclasse attributi; considera un mixin per esempio, deve essere molto attento!

Se si desidera solo nascondere l'attributo, utilizzare un trattino singolo. E come vedi non c'è magia extra da aggiungere - se non definisci una funzione set, la tua proprietà è di sola lettura come valore di ritorno di un metodo.