您能使用闭包优化函数中的导入吗?

2024-05-16 18:17:09 发布

您现在位置:Python中文网/ 问答频道 /正文

Thesetwo问题涉及在函数内部使用import,而不是在模块顶部使用。我不需要被说服把我的进口放在首位,这是有充分理由的。不过,为了更好地理解技术问题,我想问一个后续问题。你知道吗

通过使用闭包并仅在函数第一次运行时导入,您能在性能方面获得两全其美的效果吗?你知道吗


具体来说,假设您有如下代码:

import sys
def get_version():
    return sys.version

您希望导入只在函数被调用时发生,因此将其移到内部:

def get_version():
    import sys
    return sys.version

但是现在如果它经常被调用,那么它的速度会很慢,所以你可以尝试一些更复杂的方法:

def _get_version():
    import sys

    def nested():
        return sys.version

    global get_version
    get_version = nested
    return nested()
get_version = _get_version

现在至少有一个基本的性能测试表明,最后一个选项比第一个选项稍微慢一点(花费约110%的时间),但比第二个选项快得多(花费约20%的时间)。你知道吗


首先,这真的有效吗?我的测量是否准确地描述了第二个例子做了更多的工作,或者它是我如何测量事物的一个人工制品。你知道吗

第二,从关闭到第一次运行该函数之后,是否有减速?你知道吗


Tags: 模块函数importgetreturnversiondef选项
1条回答
网友
1楼 · 发布于 2024-05-16 18:17:09

闭包取消引用并不比全局查找快:

>>> import sys
>>> sys.version_info
sys.version_info(major=3, minor=6, micro=0, releaselevel='final', serial=0)
>>> from timeit import timeit
>>> glob = 'foo'
>>> def f1(): return glob
...
>>> def closure():
...     closed_over = 'bar'
...     def f2():
...         return closed_over
...     return f2
...
>>> f2 = closure()
>>> timeit(f1, number=10**7)
0.8623221110319719
>>> timeit(f2, number=10**7)
0.872071701916866

此外,即使它的速度比它快,但与可读性之间的折衷是不值得的,尤其是当您确实需要优化代码时,如果有更快的选项可用时。你知道吗

局部变量是最快的选择,如果您真的需要优化从紧循环调用的代码,正确的混合方法是使用函数参数默认值:

import sys.version

def get_version(_sys_version=sys.version):
    return _sys_version

如果您关心的是在启动时从导入加载初始文件的影响,那么您也许应该看看^{} project,它将模块的加载推迟到第一次使用它们时。你知道吗

相关问题 更多 >