将单个python .py文件拆分为具有相互依赖关系的多个文件

时间:2014-03-25 20:15:13

标签: python python-2.7

我想将一个大的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模块的可接受方式吗?如果没有,那么实现我所做的正确的方法是什么。

1 个答案:

答案 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,但您可以通过抽象到必要的级别来避免它们。