最高效的导入方式

4

从性能角度来看(时间或内存),哪种做法更好:

import pandas as pd

或者
from pandas import DataFrame, TimeSeries

最好的方法是基于我从包中导入了多少类吗?

同样地,我见过人们做这样的事情:

def foo(bar):
    from numpy import array

为什么我想在函数或方法定义中进行导入?这不意味着每次调用函数时都要执行导入吗?还是为了避免命名空间冲突?


从函数导入的一个想法是,如果没有调用该函数,则避免导入可能未安装的模块。 - chepner
3个回答

6
这是微观优化,您不必担心这个。
每个Python进程只需加载一次模块。然后导入的所有代码只需要将名称绑定到模块或在模块中定义的对象上即可。该绑定非常便宜。
此外,您的模块中的顶级代码也仅运行一次,因此绑定也只会发生一次。函数中的导入会在每次运行函数时进行绑定,但同样,这是如此便宜,以至于可以忽略不计。
在函数中导入有两个原因会产生差异:它不会将该名称放入模块的全局命名空间中(因此没有命名空间污染),并且因为该名称现在是局部的,所以使用该名称比使用全局稍微快一些。
如果您想提高性能,请关注重复执行多次的代码。导入不是问题所在。

谢谢。我实际上并没有计划使用这个来改进任何真正的代码。这只是一种学术上的好奇心。 - Batman

1
回答更一般的问题,关于何时导入,导入是依赖项。它是程序运行所需的可能存在或不存在的代码。因此,尽早导入该代码以防止在执行过程中出现愚蠢的错误是一个非常好的主意。
特别是随着pypy变得越来越流行,当导入可能存在但无法通过pypy使用时,这一点尤其正确。最好尽早失败,而不是在代码执行数小时后可能失败。
至于“import pandas as pd”与“from pandas import DataFrame, TimeSeries”的区别,这个问题涉及到多个问题(所有问题都是如此),其中一些比其他问题更重要。有命名空间的问题,可读性的问题和性能的问题。性能应该占决策的大约0.0001%,正如Martjin所述。可读性应该占90%。命名空间只有10%,因为可以如此轻松地缓解它。
个人而言,我认为import X as Yfrom X import Y都是不好的做法,因为显式优于隐式。你不想在第2000行尝试记住“calculate_mean”来自哪个包,因为它在代码中没有被引用。当我第一次开始使用numpy时,我从互联网上复制/粘贴代码,但无法弄清楚为什么我不能pip install np。如果您具有关于“np”是Python中“numpy”的知识,则这显然不是问题,但对于它所节省的3个字母而言,这是一个愚蠢且无意义的困扰。它源自numpy。使用numpy。

0
在函数内导入模块有一个还没有被提及的优点:这样做可以让你控制模块何时被加载。事实上,即使@J.J的答案建议尽早导入所有模块,这种控制也允许你推迟加载模块。
为什么要这样做呢?虽然这不会改善程序的实际性能,但这样做可以提高用户的感知性能,从而提高用户体验

在某种程度上,用户根据启动应用程序所需的时间来判断其快慢。

MSDN:提高应用程序启动性能的最佳实践

在主脚本开始时加载每个模块可能需要一些时间。例如,我的一个应用程序使用了Qt框架、Pandas、Numpy和Matplotlib。如果所有这些模块都在应用程序的开头被导入,用户界面的出现会延迟几秒钟。用户不喜欢等待,因此他们可能会认为您的应用程序总体上很慢。

但是,如果例如Matplotlib仅从调用绘图命令的那些函数中导入,启动时间就会明显缩短。用户不再感觉您的应用程序那么缓慢,这可能会带来更好的用户体验。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接