Domanda

Una delle cose veramente belle di Python è la semplicità con cui puoi nominare variabili che hanno lo stesso nome dell'accessor:

self.__value = 1

def value():
    return self.__value

Esiste un modo semplice per fornire l'accesso ai membri privati ??di una classe che desidero sottoclassare? Spesso desidero semplicemente lavorare con gli oggetti di dati non elaborati all'interno di una classe senza dover utilizzare continuamente accessor e mutatori.

So che questo sembra andare contro l'idea generale di privato e pubblico, ma di solito la classe che sto cercando di sottoclassare è una delle mie e sono abbastanza felice di esporre i membri da una sottoclasse ma non a un'istanza di quella classe. Esiste un modo pulito per fornire questa distinzione?

È stato utile?

Soluzione

Non convenientemente, senza ulteriori incapsulamenti. L'attributo double-underscore è alterato dal nome anteponendo '_ClassName' per la classe a cui si accede. Quindi, se si dispone di una classe 'ContainerThing' che ha un attributo '__value', l'attributo viene effettivamente archiviato come '< code> _ContainerThing__value '. Cambiare il nome della classe (o refactoring a cui è assegnato l'attributo) significherebbe interrompere tutte le sottoclassi che tentano di accedere a quell'attributo.

Questo è esattamente il motivo per cui il double-underscore name-mangling (che non è in realtà "privato", solo "scomodo") è una cattiva idea da usare. Usa solo un singolo carattere di sottolineatura iniziale. Tutti sapranno non toccare il tuo attributo "privato" e sarai comunque in grado di accedervi in ??sottoclassi e altre situazioni in cui è dannatamente utile. La modifica del nome degli attributi con doppio trattino basso è utile solo per evitare scontri per attributi veramente specifici per una particolare classe, il che è estremamente raro. Non fornisce ulteriore "sicurezza" poiché anche gli attributi distorti dal nome sono banalmente accessibili.

Per la cronaca, ' __value ' e ' value ' (e ' _value ') non hanno lo stesso nome. I caratteri di sottolineatura fanno parte del nome.

Altri suggerimenti

" So che questo sembra andare contro l'idea generale di privato e pubblico " Non proprio "contro", solo diverso da C ++ e Java.

Privato - come implementato in C ++ e Java non è un concetto molto utile. Aiuta, a volte, a isolare i dettagli dell'implementazione. Ma è troppo abusato.

I nomi Python che iniziano con due __ sono speciali e non dovresti, come una cosa normale, definire attributi con nomi come questo. I nomi con __ sono speciali e fanno parte dell'implementazione. Ed esposto per il tuo uso.

I nomi che iniziano con un _ sono " private " ;. A volte sono nascosti, un po '. Il più delle volte, gli adulti "consenzienti" si applica la regola - non usarli scioccamente, sono soggetti a modifiche senza preavviso.

Mettiamo " privato " tra virgolette perché è solo un accordo tra te e i tuoi utenti. Hai contrassegnato le cose con _ . I tuoi utenti (e te stesso) dovrebbero onorarlo.

Spesso, abbiamo nomi di funzioni di metodo con un _ iniziale per indicare che li consideriamo come "privati". e soggetto a modifiche senza preavviso.

I getter e setter infiniti richiesti da Java non sono usati così spesso in Python. L'introspezione di Python è più flessibile, hai accesso al dizionario interno dei valori degli attributi di un oggetto e hai la prima classe funzioni come getattr () e setattr () .

Inoltre, hai la funzione property () che viene spesso utilizzata per associare getter e setter a un singolo nome che si comporta come un semplice attributo, ma in realtà è una funzione del metodo ben definita chiama.

Non sono sicuro di dove citarlo, ma la seguente dichiarazione in merito alla protezione dell'accesso è il canone Pythonic: " Siamo tutti consenzienti adulti qui " ;.

Proprio come ha affermato Thomas Wouters, un singolo trattino di sottolineatura è il modo idiomatico di contrassegnare un attributo come parte dello stato interno dell'oggetto. Due caratteri di sottolineatura forniscono solo la modifica del nome per impedire un facile accesso all'attributo.

Dopodiché, dovresti semplicemente aspettarti che il cliente della tua libreria non si spari e si spari in un piede intromettendosi con il "privato". attributi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top