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?
Odpowiedz
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
.
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
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.
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. –
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
"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. –