Почему __ main __.py требует импорта классов? - PullRequest
0 голосов
/ 25 марта 2020

У меня есть 3 сценария:

-Script A - использование некоторого класса X (сначала, взятие экземпляров из pickle, в случае необходимости)

-Script B - использование сценария A

-Test

Каждый из них может быть запущен отдельно (__name __ == '__ main __') и:

a. Конечно, когда я запускаю скрипт A напрямую, я должен импортировать класс X, но он работает.

b. Когда я запускаю скрипт B напрямую, он не работает сам по себе. Объявление X в сценарии A недостаточно. Я должен объявить это также в сценарии B. Он показывает:

AttributeError: Невозможно получить атрибут «Доктор» для

Но я могу импортировать X в сценарии B - кажется, что он не используется - и тогда все работает.

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

Сейчас:

  1. Почему это исправление работает в сценарии B в ситуации B?

  2. Почему __ main __ требует объявления X для работы?

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

Я сомневаюсь, что это имеет какое-то значение здесь, но в сценарии B и тесты (пакет unittest и flask -tests) Я использую flask.

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

some_dir / script_creating_pickle.py <- этот каталог должен быть создан </p>

import pickle

class X:

def __init__(self, A):
    self.some_variable = A

def foo(self):
    pass

X_class_dict = {}

for loop in range(5):
    X_class_dict[str(loop)] = X(loop)

with open('some_pickle.pickle', 'wb')as handle:
    pickle.dump(X_class_dict, handle, protocol=pickle.HIGHEST_PROTOCOL)

scriptA:

import pickle
from some_dir2.script_creating_pickle import X


with open('some_pickle.pickle', 'rb') as f:
    X_class_dict = pickle.load(f)

def foo2():
    class_list = []
    for key in X_class_dict.keys():

        class_list.append(X_class_dict[key])
print(class_list)

foo2()

scriptB:

from scriptA import foo2
foo2()

Пример не содержит критерий, но он вырастет до большого и может оказаться не таким уж важным Вот.

При создании минимального воспроизводимого примера меня спросили в комментариях, я столкнулся с новым механизмом c Я не понимаю, и это становится частью вопроса. Для воспроизведения сначала запустите сценарий создания pickle и переместите созданный файл в основной каталог. Затем запустите сценарии A и B сначала без , затем с импортом, а затем снова без их.

Теперь новую механику я не понимаю :

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

ModuleNotFoundError: Ни один модуль с именем some_dir

ScriptA также будет вызываться затем эта ошибка.

Итак, новый вопрос: почему ScriptA нужно запускать один раз с импортом, но после комментирования импорта он все еще запоминает его?

Вот изображение всего проекта:

Entire working directory

...