【问题标题】:Difference between importing python library within function versus importing globally?在函数内导入 python 库与全局导入之间的区别?
【发布时间】:2017-10-10 18:55:39
【问题描述】:

假设我想导入一个 python 库以在函数内部使用。是在函数内导入库还是全局导入更好?

这样做

def test_func:
    import pandas as pd
    # code implementation

或者在 python 文件的顶部有下面的行来全局导入?

import pandas as pd

每种方法的优缺点是什么?哪个是python的最佳实践?

我正在使用 python v3.6

编辑:做一些澄清。

假设我有 2 个函数。

def func1:
    import pandas as pd
    # code implementation   

def func2:
    import pandas as pd
    # code implementation   

python 脚本运行这两个函数。库会被导入两次,还是 python 编译器足够聪明,只导入一次?这会影响性能。

【问题讨论】:

    标签: python python-3.x python-import


    【解决方案1】:

    这是名称可见性和执行时间点的差异。当您正在加载的文件被导入或运行时,模块级导入被导入。显然,只有在运行该函数时,该函数才是本地函数。导入的名称要么对文件中的所有内容可见,要么仅在执行导入的函数中可见。

    由于点击 import 语句是有代价的(虽然很小,但仍然如此),本地语句将总是执行,而不仅仅是一次。但它不会完全重新导入模块,python 会在第一次导入模块后缓存模块(参见 reloadsys.modules)。

    显然,最佳实践是使用模块级导入,这就是您在 99.999% 的代码中看到的。一个重要的原因是可维护性 - 如果您想了解模块具有哪些依赖项,只需查看顶部即可方便,而不必梳理所有代码。

    那么什么时候使用函数本地导入呢?

    共有三种情况:

    • 您不能更早地使用导入。这发生在例如在运行时通过配置或系统检查选择数据库或其他系统/功能的后端。

    • 否则你有循环导入。这是一种罕见的情况,也是代码异味,因此如果有必要,请考虑重构。

    • 通过延迟模块导入来减少启动时间。不过这很少有用。

    因此,对于您的情况,答案是快速简单的“不要这样做”。

    【讨论】:

    • 我对问题进行了一些编辑以进一步澄清。你愿意帮忙吗?谢谢。
    【解决方案2】:

    模块会在你导入的时候被加载,所以如果你需要导入一个很少使用的模块,但初始化的时间很长,你应该在需要的时候导入它。

    实际上,如果我们只关心性能而不关心可读性,那么在我们真正需要的时候导入模块可能总是更好。

    但是我们需要保持我们的程序可维护。在顶部导入所有模块是告诉他人和自己编写使用哪些模块的最明确方式。

    综上所述,如果你真的有一个非常昂贵但很少使用的模块,你应该在本地导入它。否则你应该在顶部导入它们。

    【讨论】:

    • 您对性能的评论具有误导性。导入将始终在函数运行时执行。虽然模块本身不会在缓存时重新加载,但它会执行代码。很好的维护!
    • @deets 看来您误解了我的意思是“维护”?我当然知道只使用缓存重新导入模块,但是你想在一个巨大的项目中找到整个文件中所有使用的模块吗?
    • 我对问题进行了一些编辑以进一步澄清。你愿意帮忙吗?谢谢。
    • @user3848207 是的,它足够聪明地缓存加载的模块。所以它只会被加载一次。
    • @Sraw 我认为我们彼此理解 :) 我完全同意在文件顶部说明依赖项更易于维护。我只是在评论性能影响:为此本地化导入是非常罕见的(我在 python 的大约 20 年中从未这样做过),并且执行本地导入语句会有 的惩罚在每个函数调用上。因此,如果该函数处于热路径中,性能将会受到负面影响。
    猜你喜欢
    • 1970-01-01
    • 2014-02-05
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-31
    • 2012-08-29
    相关资源
    最近更新 更多