Импорт функции / класса из одноименного модуля Python - PullRequest
6 голосов
/ 26 марта 2010

У меня есть пакет Python mymodule с подпакетом utils (то есть подкаталог, который содержит модули, каждый из которых имеет функцию). Функции имеют то же имя, что и файл / модуль, в котором они живут.

Я бы хотел получить доступ к функциям следующим образом,

from mymodule.utils import a_function

Как ни странно, иногда я могу импортировать функции, используя приведенную выше нотацию, но иногда я не могу. Хотя я не смог понять почему (недавно, например, я переименовал функцию и файл, в котором она находилась, и отразил это переименование в файле utils.__init__.py, но он больше не импортируется как функция (а скорее как модуль) в одном из моих сценариев.

utils.__init__.py читает что-то вроде

__all__ = ['a_function', 'b_function' ...]
from a_function import a_function
from b_function import b_function
...

mymodule.__init__.py не имеет отношения к utils

Идеи

1 Ответ

7 голосов
/ 26 марта 2010

Ваши функции утилит должны импортировать другие функции утилит? (или импортировать другие модули, которые импортируют другие функции утилит). Предположим, например, что a_function.py содержит содержит «из mymodule.utils import b_function». Вот ваш utils.py с кучей дополнительных комментариев:

# interpreter is executing utils.py
# Right now, utils.a_function and utils.b_function are modules

# The following line executes the a_function module, 
# then rebinds a_function to a_function.a_function
from a_function import a_function 

# The following line executes the b_function module, 
# then rebinds b_function to b_function.b_function
from b_function import b_function

Когда модуль a_function впервые импортируется с помощью utils.py, utils.b_function - это модуль, а не функция. Любой модуль, который сообщает «из mymodule.utils import b_function» перед выполнением последней строки, в итоге получит ссылку на модуль b_function вместо функции b_function.

В общем, я считаю, что идиома from somemodule import something таит в себе опасность для любого крупного проекта. Это отлично подходит для коротких сценариев, но как только вы начинаете вводить циклические зависимости импорта, вы сталкиваетесь с проблемами и должны быть осторожны с тем, где вы его используете.

В качестве компромисса между безопасностью и экономией при наборе текста, я бы использовал from mymodule import utils, а затем позвонил utils.a_function(). Таким образом, вы всегда будете привязывать объект к utils.a_function прямо сейчас вместо того, что было привязано к utils.a_function во время импорта.

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