从同名Python模块导入函数/类
我有一个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 个回答
你的工具函数需要引入其他工具函数吗?(或者引入其他模块,这些模块又引入了其他工具函数)。假设有一个叫做 a_function.py 的文件,它里面有一句 "from 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
当 utils.py 首次引入 a_function 模块时,utils.b_function 是一个模块,而不是一个函数。在最后一行代码执行之前,任何写了 "from 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
的任何东西。