Инициализация атрибута в дочернем классе, который используется в родительском классе - PullRequest
1 голос
/ 07 февраля 2020

Я использую стороннюю библиотеку Python ( wx Python), в которой один из модулей содержит класс ошибки.
Код проблемной части c выглядит следующим образом :

def OnText(self, event):
    value = self.GetValue()
    if value != self.__oldvalue:
        pass  # Here some more code follows ...
    self.__oldvalue = value

Проблема в выражении if, так как при первом вызове этого метода self.__oldvalue еще не был инициализирован. Так что для обходного пути, пока эта ошибка не была исправлена ​​разработчиками библиотеки, я подумал, что смогу исправить это с помощью небольшого обходного пути. Я просто хотел извлечь дочерний класс из этого неисправного класса и инициализировать self.__oldvalue в этом конструкторе:

class MyIntCtrl(wx.lib.intctrl.IntCtrl):
    def __init__(self, *args, **kw):
        self.__oldvalue = None
        super().__init__(*args, **kw)

Однако теперь, когда я использую этот новый класс MyIntCtrl вместо исходного IntCtrl класса , Я получаю точно такую ​​же ошибку, как и раньше:

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/wx/lib/intctrl.py", line 509, in OnText
    if value != self.__oldvalue:
AttributeError: 'MyIntCtrl' object has no attribute '_IntCtrl__oldvalue'

Теперь мне интересно: что я делаю не так, как еще я могу исправить эту проблему в дочернем классе?

1 Ответ

1 голос
/ 07 февраля 2020

Любой член класса, начинающийся с __ (двойное подчеркивание), является закрытым, вы можете использовать одиночное подчеркивание _ или не использовать подчеркивания в именах для доступа к ним в производных классах.

class Parent:
    def __init__(self):
        self.__private_field = "private field"
        self._protected_field = "protected field"
        self.public_field = "public field"

class Child(Parent):
    def __init__(self):
        pass

    def do(self):
        print(self.__private_field) # It will throw exception
        print(self._protected_field) # It will not throw exception
        print(self.public_field) # It will not throw exception

Или вы можете обойти частных / защищенных участников, называя их как:

print(_Parent__private_field)
...