2010-03-20 12 views
12

Mam prywatne metody def __pickSide(self): w klasie nadrzędnej, które chciałbym przesłonić w klasie podrzędnej. Jednak klasa potomna nadal wywołuje dziedziczone def __pickSide(self):. Jak mogę przesłonić funkcję? Nazwa funkcji klasy potomnej jest dokładnie taka sama jak nazwa funkcji rodzica.Jak zastąpić funkcje klasy nadrzędnej w pythonie?

+3

Proszę nie używać wszystkich tych "__". Są mylące. W Pythonie naprawdę nie ma "prywatnego". Sprawiają, że proste rzeczy wyglądają na zagmatwane. Zaktualizuj swoje pytanie za pomocą najmniejszego przykładu kodu, który pokazuje Twój problem. –

+0

To jest kod, z którym mam problem ... czego więcej chcesz? Wiem, że funkcje i zmienne "prywatne" są nadal dostępne w Pythonie, ale nie wykorzystują wszystkich publicznych funkcji, co powoduje większe zamieszanie podczas korzystania z klasy? – wrongusername

+0

"To jest kod"? Jaki kod? Czy możesz zaktualizować pytanie tak, aby rzeczywiście dostarczyć próbkę rzeczywistego kodu, który w rzeczywistości nie działa? Trudno odgadnąć, jak wygląda twój kod. Łatwo jest zakładać rzeczy; łatwo założyć, że jest źle. "czego jeszcze chcesz?" Kod. Aby przyjrzeć się i zobaczyć, jaki błąd popełniasz, a nie jaki błąd zakładam, że robisz. –

Odpowiedz

33

Miejmy w najprostszy przykład:

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) 

demontaż jest następująca:

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 

Jak widać, Python Zmieniany nazwy funkcji, które zaczynają z dwoma podkreśleniami (i dostęp do takich nazwy !!) na nazwę zawierającą nazwę klasy - w tym przypadku _A__pick i _B__pick). Oznacza to, że klasa, w której zdefiniowana jest funkcja, określa, która metoda jest wywoływana.

Rozwiązanie jest proste, unikaj pseudo-prywatnych metod, usuwając podwójne podkreślenia. Na przykład użyj _pick zamiast __pick.

5

Problemem, który widzisz, jest to, że podwójne podkreślenia nadają nazwę funkcji nawet w połączeniach. Zapobiega to poprawie działania polimorfizmu, ponieważ nazwa, na którą jest on zniekształcony, jest oparta na nazwie klasy, w której jest zdefiniowana metoda, a nie nazwie klasy obiektu, do którego się odwołuje. Zastąpienie podwójnych podkreśleń czymś innym rozwiąże ten problem. wygląd

3
  • Użycie nazwy powoduje przekształcenie nazwy metody, aby ułatwić jej dostęp do niej, gdy zajdzie taka potrzeba. Zalecam, aby nigdy ich nie używać, co sprawia, że ​​testowanie przebiega sprawniej.

  • Nie ma prywatnego w Pythonie, a jeśli tak, to i tak by to uniemożliwiło. (Jest to punkt prywatnych rzeczy w językach, które mają go.)

  • Wspólna konwencja wskazuje, że atrybut nie jest częścią interfejsu publicznego klasy go wykorzystać do jednego wiodącego podkreślenia, jak _foo . Jest to wystarczające, aby twój kod wyraźnie oddzielał twoje wewnętrzne szczegóły od publicznego API.

Powiązane problemy