Вопрос:

Объявление класса и подкласса в двух разных файлах в Python

python class import subclass

971 просмотра

3 ответа

6 Репутация автора

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

File1:

from file2 import subclass

class superclass:
    def __init__(self):
        "Stuff"

    def method(self):
        temp = subclass()
        "Stuff"

File2:

from file1 import superclass

class subclass(superclass):
    def __init__(self):
        "Stuff"

Когда я запускаю код file1, я получаю ошибку внутри file2, что суперкласс не определен. Это потому, что я импортирую file2 перед определением суперкласса.

Однако, если я импортирую file2 после определения суперкласса, я получаю ошибку в file1, говоря, что подкласс не определен. Это потому, что я использую экземпляр подкласса в методе.

Одним из решений этой проблемы является создание объявлений как суперкласса, так и подкласса в одном файле, но мне интересно, есть ли способ объявить их в разных файлах.

Автор: Keagan Источник Размещён: 21.03.2017 05:59

Ответы (3)


0 плюса

4407 Репутация автора

Получить tempиз метода и переопределить этот метод в подклассе.

class superclass:
    def get_temp(self):
        return 'a superclass temp'

    def method(self):
        temp = self.get_temp()
        print(type(self).__name__, repr(temp))

class subclass(superclass):
    def get_temp(self):
        return 'a subclass temp'


superclass().method()
subclass().method()

Выход:

superclass 'a superclass temp'
subclass 'a subclass temp'

Если вам нужно method()отличаться subclassили, возможно, выполнять какую-то работу до или после superclass.method(), используйте ключевое слово super .

Автор: Harvey Размещён: 21.03.2017 06:16

0 плюса

616 Репутация автора

Вы можете включить следующую строку в ваш файл2:

if superclass in locals(): print pass
else: 'Please define superclass'

Нравится:

File2:

from file1 import superclass

class subclass(superclass):
    if superclass in locals(): pass
    else: print 'Please define superclass'
    def __init__(self):
        "Stuff"

Теперь попробуйте запустить файл1, а НЕ файл2. Появится запрос «Пожалуйста, определите суперкласс». Но подкласс был зарегистрирован. Как только вы запустите что-то вроде:

x = superclass()

Подкласс становится работоспособным.

Автор: Ishan Tomar Размещён: 21.03.2017 07:31

0 плюса

1215 Репутация автора

Проблема легко понять, если вы посмотрите, как Python загружает модули:

  1. Ты бежишь python file2.py.
  2. Python загружается file2.pyи начинает его выполнять.
  3. Python разбирает from file1 import superclass.
  4. Python загружается file1.pyи начинает его выполнять.
  5. Python разбирает from file2 import subclass.
  6. Как file2уже загружено, Python пытается получить доступ file2.subclass.
  7. Python еще не проанализировал оператор класса, поэтому subclassеще не существует. Это вызывает ImportError.

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

1) импорт file2в самом методе.

class superclass:
    def __init__(self):
        "Stuff"

    def method(self):
        from file2 import subclass
        temp = subclass()
        "Stuff"

Это вызывает импорт при methodпервом вызове, а не при импорте / загрузке file1. Недостатком является то, что при каждом methodвызове возникают накладные расходы времени выполнения, и вы должны убедиться, что он method()вызывается только после завершения импорта file1.

2) импорт file2в конце file1без использования from import.

class superclass:
    def __init__(self):
        "Stuff"

    def method(self):
        temp = file1.subclass()
        "Stuff"

import file2

Таким образом, циклический импорт file2происходит, когда он superclassуже существует в пространстве имен file1. В то время пространство имен file2является неполным ( file2.subclassеще не существует, поэтому from file2 import subclassможет потерпеть неудачу), но до тех пор, пока methodон не был вызван до успешного импорта, он работает. Недостатком является то, что вам необходимо отслеживать, какие операторы импорта должны находиться внизу файла, а какие - вверху. Любая ошибка приведет к тому, ImportErrorsчто ее будет трудно отследить, если иерархия вашего модуля станет более сложной.

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

Автор: cg909 Размещён: 21.03.2017 08:08
Вопросы из категории :
32x32