如何将多个Python源文件合并为一个文件?

4 投票
4 回答
2978 浏览
提问于 2025-04-15 15:08

(假设:应用程序的启动时间非常关键;我的应用程序启动频繁;我的应用程序运行在一个导入速度比平常慢的环境中;需要导入很多文件;并且不能编译成 .pyc 文件。)

我想把所有定义了一组模块的 Python 源文件合并成一个新的 Python 源文件。

我希望导入这个新文件的效果就像我导入其中一个原始文件一样(然后这个原始文件会再导入其他一些原始文件,依此类推)。

这样做可能吗?

下面是一个粗略的手动模拟,展示了一个工具在处理模块 'bar' 和 'baz' 的源文件时可能产生的结果。你会在部署代码之前运行这样的工具。

__file__ = 'foo.py'

def _module(_name):
    import types
    mod = types.ModuleType(name)
    mod.__file__ = __file__
    sys.modules[module_name] = mod
    return mod

def _bar_module():

    def hello():
        print 'Hello World! BAR'

    mod = create_module('foo.bar')
    mod.hello = hello
    return mod

bar = _bar_module()
del _bar_module

def _baz_module():

    def hello():
        print 'Hello World! BAZ'

    mod = create_module('foo.bar.baz')
    mod.hello = hello
    return mod

baz = _baz_module()
del _baz_module

现在你可以:

from foo.bar import hello
hello()

这段代码没有考虑像导入语句和依赖关系这样的东西。有没有现成的代码可以用来通过这种方式,或者其他技术来组合源文件?

这个想法和一些工具在发送 JavaScript 文件到浏览器之前进行组合和优化的方式非常相似,因为多个 HTTP 请求的延迟会影响性能。在这个 Python 的例子中,问题在于启动时导入数百个 Python 源文件的延迟会造成影响。

4 个回答

0

这样做不太可能带来性能上的提升。你仍然是在导入相同数量的Python代码,只是模块变少了而已——而且你为了这个牺牲了模块化的好处。

更好的方法是修改你的代码和/或库,只在需要的时候导入东西,这样每次请求时只加载最少的必要代码。

1

我觉得因为Python文件在运行之前会被预编译,还有一些系统缓存的原因,你最终得到的速度提升是很难被测量出来的。

3

如果你在使用谷歌应用引擎(Google App Engine),那么请确保你使用了这个方法。

def main(): 
    #do stuff
if __name__ == '__main__':
    main()

因为谷歌应用引擎不会在每次请求时重启你的应用,除非你的.py文件有变化,它只是再次运行 main() 函数。

这个技巧可以让你写出类似CGI风格的应用,而不会因为启动而影响性能。

应用缓存

如果一个处理脚本提供了一个 main() 函数,运行环境会缓存这个脚本。否则,每次请求时都会加载这个处理脚本。

撰写回答