переопределить "частный" метод в Python
рассмотрим класс с "частным" методом, таким как:
class Foo(object):
def __init__(self):
self.__method()
def __method(self):
print('42')
когда я пытаюсь подкласс Foo
и переопределить метод __method
, видно, что Foo.__method
по-прежнему называется, а не MoreFoo.__method
.
class MoreFoo(Foo):
def __method(self):
print('41')
>>> MoreFoo()
42
<__main__.MoreFoo object at 0x7fb726197d90>
каков был бы способ переопределить такой метод?
3 ответов
на точка использование соглашения о двойном подчеркивании имен-это предотвращение (случайного) переопределения подклассов методом.
Если вы есть чтобы переопределить его в любом случае, кто-то сделал серьезную ошибку дизайна класса. Вы можете сделать это еще, назвав свой объект так:
def _Foo__method(self):
где вы префикс имя метода с еще одним подчеркиванием и определяющим classname (так что в этом случае с префиксом _Foo
). Процесс переименования методы и атрибуты с двойным подчеркиванием называются частное имя коверкая.
Если вы хотите определить "частный" метод, который по-прежнему переопределяется в подклассе, вы обычно придерживаетесь имен с одним подчеркиванием (def _method(self):
).
из-за его динамической природы почти ничего в Python не является действительно частным; с небольшим самоанализом почти все может быть достигнуто.
двойной префикс подчеркивания вызывает искажение имени, это не эквивалент частного метода. Он специально разработан, чтобы избежать переопределения подклассами (и в этом случае имя метода становится _Foo__method
).
если у вас есть детали реализации, префикс его с одним подчеркиванием, это универсально принятый знак для методов Python, которые не должны использоваться извне. Нет никакого принуждения к этому, потому что это не так, как Python функции.
Я считаю, что вы сделали бы что-то вроде:
class MoreFoo(Foo):
def _Foo__method(self):
print('41')
as документирована.
любой идентификатор формы
__spam
(не менее двух ведущих подчеркиваний, не более одного завершающего подчеркивания) текстуально заменяется на_classname__spam
, гдеclassname
- это текущее имя класса с начальным подчеркиванием(подчеркиванием).
но дизайнеры оригинального класса придерживались мнения, что вам не нужно делать что-то подобное поскольку трудно переопределить подклассы, весь смысл двойных подчеркиваний начинается с:
name mangling полезно для разрешения подклассов переопределять методы без нарушения внутриклассных вызовов методов.