我想将一个大的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模块的可接受方式吗?如果没有,那么实现我所做的正确的方法是什么。
答案 0 :(得分:4)
&#34;正确&#34;方法是在需要的地方导入必要的模块:
# 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,但您可以通过抽象到必要的级别来避免它们。