【问题标题】:Is it okay to import sys inside a function to check if a module has been imported?是否可以在函数中导入 sys 以检查模块是否已导入?
【发布时间】:2018-01-23 13:51:27
【问题描述】:

我想要一个函数在运行函数中的其他行之前快速检查模块是否存在。它可能在大型代码库中的其他几个程序中执行,我不想在它运行的任何地方在顶部导入sys

This answer 解释了检查模块是否存在的过程。

>>> import sys
>>> 'unicodedata' in sys.modules
False
>>> import unicodedata
>>> 'unicodedata' in sys.modules
True

Here 很多人就何时可以在函数中导入发表意见。

以下具体用法可以吗?

def some_function(foo):
    import sys
    if 'pandas' in sys.modules:
        if isinstance(foo, pd.DataFrame):
            # function continues
    else:
        print("pandas has not been imported in the code you are testing")

用例首先检查 pandas 数据框是否满足各种条件,如果满足则执行其他操作。问题是,查看代码库我不能总是确定我正在测试函数的东西是否是一个数据框,所以一直在做if is instance(variable, pd.DataFrame)。但是,如果函数被导入某个地方并在根本没有 pandas 的地方运行呢?我宁愿它刚刚意识到这一点,也不愿让整个程序崩溃或不必要地导入 pandas。

【问题讨论】:

  • 如果您需要导入特定模块以运行代码,只需导入模块。为什么需要检查模块?如果您不分享您的用例,我们无法开始告诉您是否可以。
  • 否则,sys 是一个内置模块,从 Python 解释器启动的那一刻起就存在(这对于 Python 的运行来说是相当关键的),所以导入 sys 除了只是设置名称sys 以引用模块对象。进口几乎是零成本。
  • @MartijnPieters 添加了一个用例
  • 内置异常ImportError 可能对这个检查有用。 docs.python.org/2/library/…
  • 使用pd.DataFrame的代码进行导入,没有导入函数的代码。 这不是导入函数的模块需要担心的事情。如果您担心已安装 的依赖项,则无法使用sys.modules 测试对其进行测试,因为它仅列出已导入的模块。 import pandas as pd 语句将抛出 ImportError 如果未安装模块,只需处理该异常。

标签: python python-3.x


【解决方案1】:

您似乎对已安装的库和已导入的库感到困惑。

您的用例似乎与未安装 Pandas 有关。您无法使用sys.modules 测试这种可能性。只需让您的代码导入 Pandas,并在它不可用时处理抛出的 ImportError

try:
    import pandas as pd

    def is_dataframe(obj):
        return isinstance(obj, pd.DataFrame)
except ImportError:
    def is_dataframe(obj):
        return False

上面的代码对数据帧类型的测试进行了编码,如果没有安装 Pandas,它将继续工作。

如果您的代码需要考虑到某些第三方库返回数据帧的可能性,只需使用上面的代码来测试这种意外情况(但前提是您不能以其他方式使您的代码工作,就像如果某些东西不是您期望处理的类型时捕获异常)。不要试图猜测 Pandas 是否真的在某个地方使用。要么处理数据帧,要么不处理,没有必要使这个动态化。如果obj 不是数据框,则isinstance(obj, pd.DataFrame) 测试不会抛出异常,这里没有风险

请注意,如果您确实尝试测试正在导入的模块,但发现它不是,并且只有另一个模块导入了 Pandas,那么您进行了错误的调用并且您的代码中断了。 Python 是一种动态语言,可以在程序运行期间的任何时间进行导入。

否则,如果安装了 Pandas,并且某些第三方模块导入 Pandas 来完成他们的工作,而您担心它们可能会这样做,您的代码无需担心这个。您无需查看第三方模块是否使用 Pandas,它不会对您的代码产生影响。 Pandas 只是另一个模块的实现细节。

最后,如果第三方模块导入 Pandas,您自己的模块也不会看到它。您需要为该模块的所有依赖项使用import 语句,在这里导入另一个模块并不重要,因为每个模块都是一个单独的命名空间。您不能只使用 pd.DataFrame 而没有 import 语句(或将名称 pd 绑定到模块对象的其他方式),而不管其他模块是否已导入它。

【讨论】:

  • Pandas 肯定已安装,抱歉我在这里并不总是更清楚:( 只是大约 30 个 .py 文件中的一些导入它而其他文件没有。我希望我的功能检查它运行的环境。我很想只使用在函数中导入 sys 的代码,直到有人可能在合并之前抱怨它。
  • @cardamom:但是为什么?如果您不测试已导入的 Pandas,会发生什么?
  • if is instance(variable, pd.DataFrame) 不仅不会执行,还会使程序崩溃!甚至没有机会拥有 else 子句。
  • @cardamom:另外,为什么要征求我们的意见,然后忽略这些意见?如果您不理解我的建议或者您认为我不理解您的情况,请更新您的问题,以更清楚地了解您要解决的问题。一些说明问题的代码在这里可能会有所帮助。
  • @cardamom: 澄清一点:其他模块是否导入了 pandas 并不重要。您需要在想要使用 Pandas 的模块中使用import 语句。除非您自己导入 pandas,否则您将总是收到名称错误,当另一个模块导入 Pandas 时,名称错误不会消失。
猜你喜欢
  • 2015-08-09
  • 1970-01-01
  • 1970-01-01
  • 2020-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-11
相关资源
最近更新 更多