Что-то не так с действительно большим __init__? - PullRequest
5 голосов
/ 19 сентября 2010

Я пишу программу на Python с графическим интерфейсом, созданным с помощью модуля Tkinter. Я использую класс для определения графического интерфейса, потому что он облегчает передачу команд кнопкам и немного облегчает понимание всего этого.

Фактическая инициализация моего графического интерфейса занимает около 150 строк кода. Чтобы это было легче понять, я написал функцию __init__ так:

def __init__(self, root):
    self.root = root
    self._init_menu()
    self._init_connectbar()
    self._init_usertree()
    self._init_remotetree()
    self._init_bottom()

, где _init_menu(), _init_connectbar() и т. Д. Выполняют всю работу по инициализации. Это облегчает отслеживание моего кода и предотвращает слишком большое увеличение __init__.

Однако это создает проблемы с областью действия. Поскольку виджет Entry, который я определил в _init_connectbar(), находится в области действия функции и не является атрибутом класса, я не могу ссылаться на него в других методах класса.

Я могу устранить эти проблемы, выполнив большую часть инициализации в __init__, но я потеряю абстракцию, полученную моим первым методом.

Должен ли я развернуть __init__ или найти другой способ перевести виджеты в область видимости класса?

Ответы [ 4 ]

5 голосов
/ 19 сентября 2010

Либо сохраняйте некоторые из этих ссылок на виджеты в переменных экземпляра, либо возвращайте их (минимальное задание, которое вы хотите; вы хотите уменьшить связь) и сохраняйте их в локальных переменных в __init__, прежде чем передавать соответствующие в качестве аргументов для вашей последующей конструкции.хелперы.Последнее чище, но требует, чтобы вещи были достаточно разделены, чтобы вы могли создать порядок, который делает это возможным.

2 голосов
/ 19 сентября 2010

По моему мнению, вы должны хранить виджеты как переменные экземпляра, чтобы вы могли ссылаться на них из любого метода. Как и в большинстве языков программирования, читаемость уменьшается, когда функции становятся слишком большими, поэтому ваш подход разделения кода инициализации - хорошая идея.

Когда сам класс становится слишком большим для одного исходного файла, вы также можете разделить класс с помощью смешанных классов (аналогично частичным классам в C #).

Например:

class MainGuiClass(GuiMixin_FunctionalityA, GuiMixin_FunctionalityB):
    def __init__(self):
        GuiMixin_FunctionalityA.__init__(self)
        GuiMixin_FunctionalityB.__init__(self)

Это удобно, когда графический интерфейс пользователя состоит из различных функций (например, вкладка конфигурации, вкладка выполнения или что-то еще).

1 голос
/ 19 сентября 2010

Почему бы вам не создать свои виджеты, на которые нужно ссылаться, переменные экземпляра.Это то, что я обычно делаю, и, похоже, это довольно распространенный подход.

например

self.some_widget
1 голос
/ 19 сентября 2010

Вы должны посмотреть шаблон строителя для такого рода вещей.Если ваш GUI сложный, то в его описании будут некоторые сложности.Является ли это сложной функцией или сложным описанием в каком-либо файле, сводится к одному и тому же.Вы можете просто попытаться сделать его максимально читабельным и понятным, и, по моему опыту, здесь очень помогает шаблон построения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...