Почему один и тот же код в одном файле импортирует функцию, а в другом файле - модуль с тем же именем? - PullRequest
1 голос
/ 07 мая 2020

Один и тот же оператор импорта from mypackage._aux import is_error имеет два разных значения в похожих файлах:

Первое - это ожидаемое поведение, потому что _aux/__init__.py содержит from .is_error._is_error import is_error. (формат from .folder.file import function)

Когда я запускаю pytest, два теста в _abbrev_testing_test.py терпят неудачу, потому что is_error не является ожидаемой функцией. (TypeError: 'module' object is not callable)

Это работает, когда я использую строку, которую я хотел бы сократить с помощью новой функции: enter image description here Это включает тест в _foobar_test.py - поэтому в _foobar.py была импортирована функция .

Но в _abbrev_testing.py был импортирован модуль : enter image description here

Кто-нибудь понимает разницу между двумя файлами? Должен ли я сделать это по-другому?

Я хотел бы знать, есть ли какое-нибудь логическое правило, которое позволило бы этого избежать. (Для меня это выглядит абсурдно и ошибочно c.)

Изменить: В обоих файлах это работает, когда я использую длинный оператор импорта, не полагающийся на _aux/__init__.py :

  • короткое: from mypackage._aux import is_error (формат from _aux import function)

  • длинный: from mypackage._aux.is_error._is_error import is_error
    (формат from _aux.folder.file import function)

Этот вопрос можно резюмировать следующим образом:
Что в _abbrev_testing.py саботирует __init__.py?

Редактировать 2: Шаги для воспроизведения:

me@ubuntu:~$ git clone https://github.com/watchduck/module_object_is_not_callable.git
me@ubuntu:~$ cd module_object_is_not_callable/
me@ubuntu:~/module_object_is_not_callable$ virtualenv -p python3 env

Открыть проект в IDE.

(env) me@ubuntu:~/module_object_is_not_callable$ pip install pytest
(env) me@ubuntu:~/module_object_is_not_callable$ pytest

1 Ответ

0 голосов
/ 10 мая 2020

Что в _abbrev_testing.py саботирует init .py?

Попался - если вы измените:

from .is_error._is_error import is_error
from .abbrev_testing._abbrev_testing import abbrev_testing
from .foobar._foobar import foobar

в вашем Проблема с инициализацией уходит. Вы были:

from .abbrev_testing._abbrev_testing import abbrev_testing
from .is_error._is_error import is_error

установка is_error для функции только "is_error" после вы импортировали .abbrev_testing._abbrev_testing - где is_error (правильно) уже был импортирован как модуль.

Следует ли мне сделать это по-другому?

Конечно. Не называйте функции такими же именами, как модули / пакеты. Это разные вещи, поэтому должны иметь разные названия. Также - избегайте похожих повторяющихся имен и ведущих знаков подчеркивания. Делает код очень трудным для чтения (поэтому я много раз открывал _abbrev_testing_errors.py, потому что он выглядел очень похоже на _abbrev_testing.py или _abbrev_testing_test.py) - оставьте «тест» для тестов. Я говорю это со всей серьезностью - система импорта python сложна, но сложность обусловлена, потому что это сложная проблема. Правильное именование делает эту сложность управляемой.

...