2012-02-04 16 views
14

Come posso chiamare una funzione privata da qualche altra funzione all'interno della stessa classe?Chiamare la funzione privata all'interno della stessa classe python

class Foo: 
    def __bar(arg): 
    #do something 
    def baz(self, arg): 
    #want to call __bar 

Proprio ora, quando faccio questo:

__bar(val) 

da Baz(), ottengo questo:

NameError: global name '_Foo__createCodeBehind' is not defined 

Qualcuno può dirmi quale sia la ragione dell'errore è? Inoltre, come posso chiamare una funzione privata da un'altra funzione privata?

risposta

18

Non c'è alcun this-> implicito in Python come in C/C++ ecc. È necessario chiamarlo su self.

class Foo: 
    def __bar(self, arg): 
     #do something 
    def baz(self, arg): 
     self.__bar(arg) 

Questi metodi non sono davvero privato però. Quando si avvia un nome di metodo con due caratteri di sottolineatura, Python esegue un po 'di manomissione dei nomi per renderlo "privato" e questo è tutto ciò che fa, non impone nulla come le altre lingue. Se si definisce __bar su Foo, è ancora accessibile dall'esterno dell'oggetto tramite Foo._Foo__bar. Per esempio, si può fare questo:

f = Foo() 
f._Foo__bar('a') 

Questo spiega l'identificatore "strano" nel messaggio di errore che hai pure.

Lo puoi trovare nel documento here.

5

__bar è "privato" (nel senso che il suo nome è stato mangled), ma è ancora un metodo di Foo, quindi bisogna fare riferimento a esso tramite self e passare self ad esso. Basta chiamare con un semplice __bar() non funzionerà; devi chiamarlo così: self.__bar(). Quindi ...

>>> class Foo(object): 
... def __bar(self, arg): 
...  print '__bar called with arg ' + arg 
... def baz(self, arg): 
...  self.__bar(arg) 
... 
>>> f = Foo() 
>>> f.baz('a') 
__bar called with arg a 

È possibile accedere self.__bar ovunque all'interno della vostra Foo definizione, ma una volta che sei fuori della definizione, è necessario utilizzare foo_object._Foo__bar(). Ciò consente di evitare le collisioni nello spazio dei nomi nel contesto dell'ereditarietà delle classi. Se questo non è il motivo per cui stai usando questa funzione, probabilmente stai usando in modo errato.

Problemi correlati