避免在Python包中使用相同函数的多个定义

时间:2017-04-10 16:14:07

标签: python

考虑以下python包结构

 working_directory/
-- test_run.py
-- mypackge/
---- __init__.py
---- file1.py
---- file2.py

内部file1.pyfile2.py我分别定义了函数func1()func2()。现在,要运行,func2()需要使用func1(),我可以简单地用from file1 import func1导入file2.py中的func1(),但由于整个包将被加载在一起,我可能会使用{{1}从名称空间开始,它已经被加载了。我怎么能这样做以避免在多个地方定义func1()?

2 个答案:

答案 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时,无法从第一级直接访问它们。