2010-08-02 14 views
62

Eventuali duplicati:
The meaning of a single- and a double-underscore before an object name in PythonVariabili private e Metodi Python

Quale dovrei usare _foo (un trattino) o __bar (doppia sottolineatura) per i soci privati ​​e metodi in Python?

+1

Grazie a tutti. Ho trovato un altro argomento che è utile. http://stackoverflow.com/questions/70528/why-are-pythons-private-methods-not-actually-private – kurikintoki

+1

Better: http://stackoverflow.com/questions/1301346/the-mating-of-a- single-and-a-double-underscore-before-an-object-name-in-python – laffuste

risposta

33

Il doppio trattino basso. Mangia il nome in modo tale che non è possibile accedervi semplicemente tramite __fieldName dall'esterno della classe, che è ciò che si desidera iniziare se devono essere privati. (Anche se non è ancora molto difficile per accedere al campo.)

class Foo: 
    def __init__(self): 
     self.__privateField = 4; 
     print self.__privateField # yields 4 no problem 

foo = Foo() 
foo.__privateField 
# AttributeError: Foo instance has no attribute '__privateField' 

sarà accessibile attraverso _Foo__privateField invece. Ma urla "IO SONO PRIVATO NON TOCCAMI", che è meglio di niente.

64

Si noti che non esiste una cosa come "metodo privato" in Python. Doppia sottolineatura è solo mutilazione dei nomi:

>>> class A(object): 
...  def __foo(self): 
...   pass 
... 
>>> a = A() 
>>> A.__dict__.keys() 
['__dict__', '_A__foo', '__module__', '__weakref__', '__doc__'] 
>>> a._A__foo() 

Così dunque __ prefisso è utile quando è necessario la mutilazione a verificarsi, ad esempio, di non scontrarsi con i nomi su o sotto catena di ereditarietà. Per altri usi, singolo trattino basso sarebbe meglio, IMHO.

EDIT, per quanto riguarda la confusione sulla __, PEP-8 è abbastanza chiaro su questo:

Se la classe è destinato ad essere sottoclasse, e si dispone di attributi che non si desidera sottoclassi di utilizzare, in considerazione dar loro un nome con doppio trattino di sottolineatura e nessun trattino di trascinamento. Questo richiama l'algoritmo di mangling dei nomi di Python , dove il nome della classe è manglinato nel nome dell'attributo. Ciò consente di evitare le collisioni nome attributo se le sottoclassi devono inavvertitamente contenere attributi con lo stesso nome .

Nota 3: Non a tutti piace manomettere il nome. Prova a bilanciare il necessario per evitare conflitti accidentali con un potenziale utilizzo da parte dei chiamanti avanzati .

Quindi, se non ci si aspetta che la sottoclasse riduca per errore il proprio metodo con lo stesso nome, non usarlo.

9

Doppia sottolineatura. Questo maneggia il nome. È ancora possibile accedere alla variabile, ma in genere è una cattiva idea farlo.

Utilizzare caratteri di sottolineatura singoli per semi-privato (dice agli sviluppatori di Python "cambia solo se è assolutamente necessario") e raddoppia per completamente privato.

+7

Non proprio corretto.Un singolo trattino basso significa che stai manomettendo le proprietà non documentate di un oggetto che sono soggette a modifiche e potresti rompere gli invarianti gestiti dall'oggetto, quindi dovresti capire esattamente cosa stai facendo se decidi di interrompere l'incapsulamento dell'oggetto. – msw

-3

Perché questa è la convenzione di codifica. Vedere here per ulteriori informazioni.

+4

L'OP chiedeva quale utilizzare. Non perché. – Ponkadoodle

Problemi correlati