Требует ли Python глубокого знания всех классов в цепочке наследования?

Классы Python не имеют понятия общедоступный/частный, поэтому нам говорят не трогать что-то, что начинается с подчеркивания, если мы это не создали. Но разве для этого не требуется полного знания всех классов, от которых мы прямо или косвенно наследуем? Свидетель:

class Base(object):
    def __init__(self):
        super(Base, self).__init__()
        self._foo = 0

    def foo(self):
        return self._foo + 1

class Sub(Base):
    def __init__(self):
        super(Sub, self).__init__()
        self._foo = None

Sub().foo()

Ожидаемо, TypeErrorвозникает при оценке None + 1. Поэтому я должен знать, что _fooсуществует в базовом классе. Чтобы обойти это, вместо этого можно использовать __foo, что решает проблему, искажая имя. Это кажется если не элегантным, то приемлемым решением. Однако что произойдет, если Baseнаследуется от класса (в отдельном пакете )с именем Sub? Теперь __fooв моем Subпереопределяет __fooв прародителе Sub.

Это означает, что я должен знать всю цепочку наследования, включая все «частные» объекты, которые каждый из них использует. Тот факт, что Python имеет динамическую -типизацию, еще больше усложняет задачу, так как нет объявлений для поиска. Однако худшая часть, вероятно, заключается в том, что Baseможет наследоваться от objectпрямо сейчас, но в каком-то будущем выпуске он переключится на наследование от Sub.Очевидно, что если я знаю, что Subунаследован от, я могу переименовать свой класс, как бы это ни раздражало. Но я не могу заглянуть в будущее.

Разве это не тот случай, когда истинный закрытый тип данных предотвратит проблему? Как в Python я могу быть уверен, что случайно не наступлю кому-то на пальцы ног, если эти пальцы могут возникнуть в какой-то момент в будущем?

РЕДАКТИРОВАТЬ:Я, видимо, не ясно изложил основной вопрос. Я знаком с искажением имен и разницей между одинарным и двойным подчеркиванием. Вопрос :в том, как мне справиться с тем фактом, что я могу столкнуться с классами , о существовании которых я сейчас не знаю ? Если мой родительский класс (, который находится в пакете, который я не писал ), начинает наследовать от класса с тем же именем, что и у моего класса, даже изменение имени не поможет. Я ошибаюсь, рассматривая это как (угловой )случай, который могут решить настоящие закрытые члены, но с которым у Python возникают проблемы?

РЕДАКТИРОВАТЬ:По запросу ниже приведен полный пример:

Файлparent.py:

class Sub(object):
    def __init__(self):
        self.__foo = 12
    def foo(self):
        return self.__foo + 1
class Base(Sub):
    pass

Файлsub.py:

import parent
class Sub(parent.Base):
    def __init__(self):
        super(Sub, self).__init__()
        self.__foo = None
Sub().foo()

Называется fooдедушки и бабушки, но используется мой __foo.

Очевидно, что вы не стали бы писать такой код самостоятельно, но parentможет быть легко предоставлено третьей стороной, детали которой могут измениться в любое время.

7
задан Chris 24 July 2012 в 22:12
поделиться