Если вы начнете имя метода с двух подчеркиваний, оно станет доступным только из этого класса. Рассмотрим следующий пример:
class A():
def __m(self):
pass
def m(self):
print(self.__m)
A().m() # <bound method A.__m of <__main__.A object at 0x10e0c1898>>
A().__m() # AttributeError: 'A' object has no attribute '__m'
Так что же случилось с A().__m
? Проверьте A.__dict__
, где атрибуты ищутся:
>>> A.__dict__
mappingproxy({'__module__': '__main__', '_A__m': <function A.__m at 0x10e0ab730>, 'm': <function A.m at 0x10e0ab7b8>, '__dict__': <attribute '__dict__' of 'A' objects>, '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None})
Самое главное:
'_A__m': <function A.__m at 0x10e0ab730>
Итак, функция, которую вы написали, __m
, переименована в _A__m
. Вы не предназначены для доступа к этим методам из-за пределов класса.
Если в вашем классе есть метод show
, который вызывает метод __method
(который начинается с __
), он будет вызывать только этот метод этого класса, потому что он никогда не узнает о _B__method
, только около _A__method
.
Обратите внимание, что вам никогда не следует использовать _A__method
для вызова этого метода извне класса. Если вам нужно сделать то, что вы делаете, вы должны использовать одно подчеркивание.
Если вам действительно нужно, чтобы __method
метод B
был приватным, тогда да, B
также должен переопределить show
:
class A(object):
def __method(self):
print("hello")
def show(self):
self.__method()
class B(A):
def __method(self):
print("goodbye")
def show(self):
self.__method()
A().show() ## print out hello
B().show() ## print out goodbye