Наследование в разных модулях - PullRequest
0 голосов
/ 18 октября 2018

У меня есть родительский и дочерний класс, каждый в своем отдельном файле.Если эти два класса находятся в одном файле, мой MWE работает.Если я разделю их каждый на отдельные файлы, я не знаю, как импортировать друг друга.Вот MWE:

cat test.py
#!/usr/bin/env python3

from main_win import MainWin

test = MainWin()
test.click()

cat main_win.py
#!/usr/bin/env python3

from sub_win import SubWin

class MainWin:
    def __init__(self):
        print('Created main window')
    def click(self):
        options = SubWin()

cat sub_win.py
#!/usr/bin/env python3

from main_win import MainWin

class SubWin(MainWin):
    def __init__(self):
        print('Created sub window')

Если я выполняю test.py и с циклическим импортом, определенным как выше, я получаю следующую ошибку:

ImportError: невозможно импортировать имя 'MainWin' из 'main_win' (/home/basil/scratch/trash/pythonInheritance/p03/main_win.py)

Редактировать: есть допустимыекомментарии ставят под сомнение структуру моего класса: мне нужно наследование?Могу ли я добавить суперкласс, от которого оба вышеперечисленных класса могут наследовать?Это очень хорошие комментарии, и я внимательно их рассмотрю.Конечно, MWE не поможет вам ответить на эти вопросы.А пока давайте просто предположим, что структура класса не должна изменяться.Как можно решить эту проблему?Путем объединения двух модулей в один или есть другой способ?

Ответы [ 2 ]

0 голосов
/ 18 октября 2018

Ваша проблема в том, что у вас круговая ситуация импорта.Модуль main_win импортирует sub_win, а sub_win пытается импортировать main_win назад, но он не работает правильно, потому что класс MainWin еще не существует, когда модуль sub_win пытается его импортировать.

Существует несколько возможных решений.

Часто лучшее решение - это избавиться от циклической зависимости между двумя вашими классами.Круговой импорт не запрещен, но необходимость в нем часто указывает на небрежный дизайн.Есть много способов исправить зависимость тоже.В примере кода вам не нужно SubWin для наследования от MainWin, так что вы можете просто отбросить наследование.Если им действительно нужно поделиться каким-то общим кодом или информацией, возможно, им обоим следует наследовать их от общего предка (например, Window), куда может пойти этот общий материал.Другой вариант может сделать два класса несвязанными, но MainWin передает информацию, необходимую SubWin, своему конструктору (например, options = SubWin(some_data)).

Другой вариант может заключаться в том, чтобы отложить импорт sub_win впосле MainWin существует в пространстве имен main_win.Вы можете сделать это, переместив оператор from sub_win import SubWin куда-нибудь ниже в коде.Он может либо оставаться на верхнем уровне модуля где-то ниже определения MainWin, либо его можно поместить прямо в метод click, где он используется (так что это будет локальная переменная в функции, а неглобальный).

Последняя идея - поместить ваши классы в один и тот же модуль, чтобы вам вообще не нужны операторы импорта.Если два ваших класса тесно связаны между собой, как предполагает ваш текущий дизайн, то определенно нет причин разделять их на отдельные модули.Python сильно отличается от некоторых других языков программирования (например, Java), где по умолчанию каждый класс имеет свой собственный исходный файл.Проекты Python часто содержат большие модули со многими классами и глобальными функциями.Вам нужно только разделить ваши модули, если они становятся такими большими, что вы регулярно используете часть их кода, не нуждаясь в других частях.

0 голосов
/ 18 октября 2018

У вас есть круговой импорт.main_win.py import sub_win.py, который импортирует main_win.py ...

Чтобы исправить это и оставить код как есть, вы можете технически переместить from sub_win import SubWin в MainWin.click().Хотя, определенно, это не то, что я бы предложил, и вам, вероятно, следует вернуться к разработке и пересмотреть этот подход к тому, чего вы пытаетесь достичь.

...