我想将我编写的一个大型 python 模块拆分为一个目录中的多个文件,其中每个文件都是一个函数,可能与模块中的其他函数有依赖关系,也可能没有依赖关系。这是我想出的一个简单示例:
首先,这是一个独立的 .py 模块
#[/pie.py]
def getpi():
return pi()
def pi():
return 3.1416
显然,这在导入和调用任一函数时都能正常工作。所以现在我用一个 init.py 文件把它分成不同的文件来把它包起来:
#[/pie/__init__.py]
from getpi import *
from pi import *
__all__=['getpi','pi']
#[/pie/getpi.py]
def getpi():
return pi()
#[/pie/pi.py]
def pi():
return 3.1416
因为 getpi() 与 pi() 有依赖关系,按当前结构调用它会引发异常:
>>> import pie
>>> pie.getpi()
Traceback (most recent call last):
File "<pyshell#7>", line 1, in <module>
pie.getpi()
File "C:\python\pie\getpi.py", line 2, in getpi
return pi()
NameError: global name 'pi' is not defined
因此,为了解决这个问题,我目前的解决方案是像这样编写 init.py:
#[/pie/__init__.py]
import os as _os
__all__ = []
for _f in _os.listdir(__path__[0]):
if not _f == '__init__.py' and _f.endswith('.py'):
execfile('%s\\%s'%(__path__[0],_f))
__all__.append(_os.path.splitext(_f)[0])
所以现在它工作正常:
>>> import pie
>>> pie.getpi()
3.1416
现在一切正常,就好像一切都包含在一个 .py 文件中一样。 init.py 可以包含所有单个函数所需的所有高级导入(numpy、os、sys、glob...)。
以这种方式构建模块对我来说感觉“正确”。新功能会在下次导入时自动加载(无需每次都附加 init.py)。通过查看目录中的内容,我可以一目了然地了解要使用哪些功能,此外,它还可以按字母顺序很好地对所有内容进行排序。
目前我能看到的唯一负面影响是只有 init.py 得到字节编译,而不是任何子 .py 文件。但是加载速度不是问题,所以我不介意。另外,我确实意识到这可能会导致打包问题,但我也不介意,因为我们的脚本是通过我们自己的版本控制系统分发的。
这是构建 python 模块的可接受方式吗?如果不是,那么实现我已正确完成的工作的正确方法是什么。
最佳答案
“正确”的方法是在需要的地方导入必要的模块:
# pi.py
def pi(): return 3.1417
# getpi.py
from .pi import pi
def getpi(): return pi()
# __init__.py
from .pi import *
from .getpi import *
确保你没有循环依赖。这些是 bad in any case ,但您可以通过抽象到必要的级别来避免它们。
关于python - 将单个 python .py 文件分解为多个具有相互依赖性的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22645324/