【问题标题】:Importing function from module takes very long从模块导入函数需要很长时间
【发布时间】:2017-11-25 20:30:08
【问题描述】:

当我在 python 脚本中导入我自己编写的模块函数时,加载大约需要 6 秒。该函数仅包含大约 50 行代码,但这应该无关紧要,因为它还没有执行,对吧?

这是加载函数的脚本:

#/usr/bin/env python

import time
print(time.clock())
from os import chdir
print(time.clock())
from os.path import abspath, dirname
print(time.clock())
from Project.controllers.SpiderController import RunSpider
print(time.clock())

输出如下:

0.193569
0.194114
0.194458
6.315348

我也尝试导入整个模块,但结果是一样的。

这可能是什么原因?

一些旁注:

  • 我使用 python 2.7.9
  • 模块使用scrapy框架
  • python 脚本在 Raspberry Pi 1 Model B 上运行

【问题讨论】:

  • 代码执行完毕。
  • 在前往Project.controller.SpiderController.RunSpider 的途中涉及多少__init__.py 文件?

标签: python python-2.7 time raspberry-pi scrapy


【解决方案1】:

但这应该无关紧要,因为它还没有被执行,对吧?

函数本身的代码未执行,但文件中的代码已执行。这是合乎逻辑的,因为该文件可能包含装饰器、库调用、内部常量等。该函数甚至有可能是 build(以便算法构造函数)。

使用from <module> import <item>,您可以进行几乎正常的导入,但您只创建了对该包中项目的一个引用。

因此,如果模块中编写了程序(不在if __name__ == '__main__': 范围内)或导入大量附加库时,可能需要很长时间。

例如可以构造如下函数:

def foo(x):
    return x + 5

def bar(y):
    return y * 2

def qux(x):
    return foo(bar(x))

如果您随后运行from module import qux,那么它首先必须定义foobar,因为qux 取决于这些。

此外,虽然代码本身没有被执行,但解释器会分析函数:它将源代码转换成语法树并进行一些分析(哪些变量是本地的,等等)。

最后请注意,包通常有一个__init__.py 文件,用于初始化包。该文件也会被执行,并且也可能需要相当长的时间。例如,一些具有数据库连接的包已经建立了与该数据库的连接,并且数据库可能需要一些时间才能响应连接。

【讨论】:

  • 好吧,总的来说,你所说的对我来说是有道理的。但是,即使已经创建了 *.pyc 文件,为什么还要花这么长时间呢?我的意思是这些文件只有在代码被更改的情况下才会重新生成,对吧?
  • @Praind:是的,但是您仍然必须将它们加载到内存中。不仅仅是包装本身。如前所述,它可能导致级联的导入。
猜你喜欢
  • 2017-11-13
  • 2020-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-07
  • 1970-01-01
  • 2012-08-03
  • 1970-01-01
相关资源
最近更新 更多