2010-03-20 17 views
12

Ho un metodo privato def __pickSide(self): in una classe padre che vorrei sovrascrivere nella classe figlio. Tuttavia, la classe figlio chiama ancora l'ereditato def __pickSide(self):. Come posso ignorare la funzione? Il nome della funzione della classe figlio è esattamente uguale al nome della funzione del genitore.Come sovrascrivere le funzioni di una classe genitore in python?

+3

Si prega di non utilizzare tutti quelli '__'. Stanno confondendo. Non c'è davvero "privato" in Python. Rendono le cose semplici confuse. Si prega di aggiornare la domanda con il più piccolo esempio di codice che mostra il tuo problema. –

+0

Questo è il codice con cui ho problemi ... cosa vuoi di più? So che le funzioni e le variabili "private" sono ancora accessibili in Python, ma l'utilizzo di tutte le funzioni pubbliche non renderà le cose più confuse quando si usa la classe? – wrongusername

+0

"Questo è il codice"? Quale codice? Puoi aggiornare la domanda per fornire effettivamente un esempio di codice effettivo che in realtà non funziona? È difficile indovinare a cosa assomigli il tuo codice. È facile assumere le cose; è facile dare per scontato. "Che cosa vuoi di più?" Codice. Per vedere e vedere quale errore stai effettivamente facendo, non quale errore presumo tu stia facendo. –

risposta

33

Let l'esempio più semplice:

from dis import dis 

class A(object): 
    def __pick(self): 
     print "1" 

    def doitinA(self): 
     self.__pick() 

class B(A): 
    def __pick(self): 
     print "2" 

    def doitinB(self): 
     self.__pick() 

b = B() 
b.doitinA() # prints 1 
b.doitinB() # prints 2 

dis(A.doitinA) 
print 
dis(B.doitinB) 

Lo smontaggio è la seguente:

8   0 LOAD_FAST    0 (self) 
       3 LOAD_ATTR    0 (_A__pick) 
       6 CALL_FUNCTION   0 
       9 POP_TOP 
      10 LOAD_CONST    0 (None) 
      13 RETURN_VALUE 

15   0 LOAD_FAST    0 (self) 
       3 LOAD_ATTR    0 (_B__pick) 
       6 CALL_FUNCTION   0 
       9 POP_TOP 
      10 LOAD_CONST    0 (None) 
      13 RETURN_VALUE 

Come si può vedere, Python storpia i nomi delle funzioni che iniziano con due underscore (e accessi a tale nomi !!) a un nome che include il nome della classe - in questo caso _A__pick e _B__pick). Ciò significa che la classe in cui è definita una funzione determina quale dei metodi __pick viene chiamato.

La soluzione è semplice, evitare metodi pseudo-privati ​​rimuovendo i doppi underscore. Ad esempio, utilizzare _pick anziché __pick.

5

Il problema che si sta verificando è che il doppio trattino sottolinea il nome della funzione anche nelle chiamate. Ciò impedisce al polymorphism di funzionare correttamente poiché il nome a cui è manipolato è basato sul nome della classe in cui è definito il metodo, e non sul nome della classe dell'oggetto a cui si fa riferimento. Sostituire i caratteri di sottolineatura doppia con qualcos'altro risolverà questo problema. sguardo

3
  • L'utilizzo dei nomi __foo altera il nome del metodo per rendere più semplice l'accesso quando è necessario. Consiglierei di non usarli mai, il che rende le cose come i test andare più agevolmente.

  • Non esiste un privato in Python e, in caso contrario, impedirebbe comunque di farlo. (Questo è il punto di roba privata in lingue che hanno.)

  • La convenzione comune per indicare che un attributo non è parte dell'interfaccia pubblica di una classe in modo da utilizzare un unico leader sottolineare, come _foo . Questo è sufficiente per rendere chiaro il tuo codice separando i tuoi dettagli interni dalla tua API pubblica.

Problemi correlati