考虑以下python
包结构
working_directory/
-- test_run.py
-- mypackge/
---- __init__.py
---- file1.py
---- file2.py
内部file1.py
和file2.py
我分别定义了函数func1()
和func2()
。现在,要运行,func2()需要使用func1(),我可以简单地用from file1 import func1
导入file2.py中的func1(),但由于整个包将被加载在一起,我可能会使用{{1}从名称空间开始,它已经被加载了。我怎么能这样做以避免在多个地方定义func1()?
答案 0 :(得分:0)
不会有多个定义。它们都会引用相同的加载模块。
导入模块时,如果模块已加载,则首先检查sys.modules
。如果找到它,则返回已加载的模块。无论模块如何导入,这都不会改变。
答案 1 :(得分:0)
原始问题听起来像您担心共享模块有多个定义。我认为@Vallentin已经回答说这个模块不会被加载#39;多次。如果模块在包中有别名,请务必使用一致的命名约定,以保证自己的理智。换句话说,如果在一个文件中将mymodule1
别名为mod1
,则应该在其他文件中使用相同的别名。
但是,根据您的评论,听起来您真的想要为mypackage
创建一个API,其中module1
的公共函数可以访问用户的代码test_run.py
(并且可能来自交互式解释器),同时防止module2
中的函数被用户直接访问。这是一个选择。
嵌套"私人" mypackage
内的子目录中的代码:
好处是你可以将你想要的模块直接放在包的第一层。支持模块可以放在子目录中。例如:
working_directory/
test_run.py
mypackage/
__init__.py
module1.py
utilities/
__init__.py
module2.py
# ./mypackage/__init__.py
# Use `__all__` to list modules imported by `from package_name import *`
# and used as `module_name.func_name()`
__all__ = ['module1']
# ./mypackage/module1.py
# Import modules/funcs from the utilities directory:
from utilities.module2 import func2
# Usage:
from mypackage import *
module1.func2()
# OR
from mypackage import module1
module1.func2()
# OR
import mypackage as mp
mp.module1.func2()
# BUT you cannot do:
import mypackage as mp
mp.module2.func2()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'module2'
请注意,只要用户使用点符号mypackage.utilities.module2.func2()
进行挖掘,就可以导入嵌套目录,因此它们并非真正&#34;私有&#34;。但是,导入mypackage
时,无法从第一级直接访问它们。