【问题标题】:Control python imports to reduce size and overhead控制 python 导入以减少大小和开销
【发布时间】:2012-06-22 15:27:01
【问题描述】:

我创建了许多个人库来帮助我进行日常编码。最佳做法是将导入放在 python 程序的开头。但是假设我导入了我的库,甚至只是从库中导入了一个函数或类。所有模块都被导入(即使这些模块用于其他未使用的类或函数)。我认为这会增加程序的开销?

一个例子。我有一个名为 pytools 的库,看起来像这样

import difflib

def foo():
    # uses difflib.SequenceMatcher

def bar():
    # benign function ie
    print "Hello!"
    return True

class foobar:
    def __init__():
        print "New foobar"
    def ret_true():
        return True

函数 foo 使用 difflib。现在假设我正在编写一个需要使用 bar 和 foobar 的新程序。我可以写

import pytools
...
item = pytools.foobar()
vals = pytools.bar()

或者我可以这样做

from pytools import foobar, bar
...
item = foobar()
vals = bar()

这两种选择是减少开销还是排除 foo 的导入及其对 difflib 的依赖?如果 difflib 的导入在 foo 函数内部怎么办?

我遇到的问题是将简单程序转换为仅使用库中的一两个类或函数的可执行文件时,可执行文件最终大小为 50 mb 左右。

我已经阅读了 py2exe 的优化大小页面,可以使用它的一些建议进行优化。

http://www.py2exe.org/index.cgi/OptimizingSize

我想我真的在这里寻求最佳实践。是否有某种方法可以阻止导入其依赖项位于未使用的函数或类中的库?我已经看到使用调试器执行导入语句,并且在继续之前,python 似乎只使用“def somefunction”“拾取”行。在使用函数/类之前,其余的导入是否完成?这意味着将大量导入放在函数或类的开头可以减少库其余部分的开销。

【问题讨论】:

  • 这其实是一个关于Python代码到二进制文件的转换器的问题。您使用的是哪个转换器?
  • 我不确定如何检查?如果有帮助,我正在使用 python 2.6
  • 您是在说“……将简单程序转换为可执行文件……”。您将需要一些程序来进行此转换。该程序将决定包含哪些模块。
  • 我明白了。我正在使用 py2exe。它有优化器,允许我在创建可执行文件时“排除”某些库。我想知道是否可以根据调用程序的要求动态导入内容。具体来说,如果 from X import Y 语句跳过库并仅导入函数并根据需要在导入列表中搜索依赖项
  • 我从来没有用过py2exe(我不在Windows上),所以我真的不知道它是如何工作的。

标签: python optimization import size


【解决方案1】:

有效减少依赖的唯一方法是将工具箱拆分为更小的模块,并且只导入您需要的模块。

将导入放在未使用函数的开头会阻止在运行时加载这些模块,但不鼓励这样做,因为它隐藏了依赖项。此外,无论如何,您的 Python 到可执行文件的转换器可能都需要包含这些模块,因为 Python 的动态特性使得无法静态确定实际调用了哪些函数。

【讨论】:

  • 有没有办法在程序中(对于解释器)声明将调用哪些函数或类(即使在运行时)。我对使用 from X import Y 的最初解释是告诉解释器那个特定的函数或方法是我唯一需要的。
  • @PaulSeeb:声明这一点的唯一方法是编写小模块,并且只包含您需要的模块。
  • @PaulSeeb:你最后一个问题中的“this”到底是什么?
  • 在上面的示例中,这将是 pytools。是否应该将该文件的内容分解为较小的文件以生成一个包?还是它们都是使用 from x import y 语句或 import x 语句导入的?是否有原因 python 不只是声明命名空间,并且只有在使用时才完全导入它?
  • @PaulSeeb:如果你愿意,你可以使用一个包。声明 import package 仅导入 package/__init__.py 以及由它导入的任何内容,因此您可以完全控制依赖关系。
猜你喜欢
  • 2014-03-05
  • 2019-02-28
  • 1970-01-01
  • 2017-05-07
  • 1970-01-01
  • 1970-01-01
  • 2014-04-10
  • 1970-01-01
  • 2018-07-26
相关资源
最近更新 更多