【问题标题】:How can I check if a module has been imported?如何检查模块是否已导入?
【发布时间】:2015-08-09 14:02:42
【问题描述】:

如何检查我是否在代码中的某处导入了模块?

 if not has_imported("somemodule"):
     print('you have not imported somemodule')

我想检查我是否已经导入了一个模块的原因是因为我有一个不想导入的模块,因为有时它会弄乱我的程序。

【问题讨论】:

标签: python python-import


【解决方案1】:

测试sys.modules dictionary中的模块名称:

import sys

modulename = 'datetime'
if modulename not in sys.modules:
    print 'You have not imported the {} module'.format(modulename)

来自文档:

这是一个将模块名称映射到已经加载的模块的字典。

请注意,import statement 做了两件事:

  1. 如果该模块之前从未导入过(== sys.modules 中不存在),则将其加载并添加到 sys.modules
  2. 在当前命名空间中绑定 1 个或多个引用模块对象或作为模块命名空间成员的对象的名称。

表达式modulename not in sys.modules 测试第1 步是否发生。测试第 2 步的结果需要知道使用了确切的 import 语句,因为它们设置了不同的名称来引用不同的对象:

  • import modulename 设置modulename = sys.modules['modulename']
  • import packagename.nestedmodule 设置packagename = sys.modules['packagename'](无论你添加多少额外级别)
  • import modulename as altname 设置altname = sys.module['modulename']
  • import packagename.nestedmodule as altname 设置altname = sys.modules['packagename.nestedmodule']
  • from somemodule import objectname 设置objectname = sys.modules['somemodule'].objectname
  • from packagename import nestedmodulename 设置nestedmodulename = sys.modules['packagename.nestedmodulename'](仅当在此导入之前packagename 命名空间中没有名为nestedmodulename 的对象时,此时将嵌套模块的附加名称添加到父包命名空间中)
  • from somemodule import objectname as altname 设置altname = sys.modules['somemodule'].objectname
  • from packagename import nestedmodulename as altname 设置altname = sys.modules['packagename.nestedmodulename'](仅当在此导入之前packagename 命名空间中没有名为nestedmodulename 的对象时,此时将嵌套模块的附加名称添加到父包命名空间中)

您可以测试导入对象绑定的名称是否存在于给定的命名空间中:

# is this name visible in the current scope:
'importedname' in dir()

# or, is this a name in the globals of the current module:
'importedname' in globals()

# or, does the name exist in the namespace of another module:
'importedname' in globals(sys.modules['somemodule'])

这仅告诉您名称存在(已绑定),而不是它引用特定模块或来自该模块的对象。您可以进一步检查该对象或测试它是否与 sys.modules 中可用的对象相同,如果您需要排除从那时起该名称已完全设置为其他名称。

【讨论】:

  • 这是在函数中检查所需包的最佳方法吗?也就是说,假设某些函数需要 numpy 包 - 在函数内部使用 import sys 是否最好检查它是否已导入? “最佳”是指在性能影响方面,因为每次调用函数时都会调用 import sys。谢谢
  • @Confounded 如果你担心的话,你可以简单地在函数之外导入 sys 。并不是说import sys 很贵; sys 始终存在,默认情况下已加载。但对于可选包:只需导入包。如果未安装包,则捕获ImportError 异常,并在导入成功时设置一个标志指示已安装。之后,您可以使用该标志来通知您使用可选依赖项。
  • 如何检查sys是否被导入?
  • @Fisher:你不知道。 sys 始终处于活动状态。如果您想知道sys 是否被导入到当前全局命名空间中,您可以检查名称sys 是否存在,但我看不出有任何意义。
【解决方案2】:

对于接受的 sys.modules 答案,我要添加一个警告,在导入时重命名模块时要小心:

>>> import sys
>>> import datetime as dt
>>> 'dt' in sys.modules
False
>>> 'datetime' in sys.modules
True

【讨论】:

    【解决方案3】:

    使用 sys.modules 测试模块是否被导入(我以 unicodedata 为例):

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

    【讨论】:

      【解决方案4】:

      sys.modules 包含在解释器的当前实例中任何地方使用的所有模块,因此如果在任何其他 Python 模块中导入,则会显示出来。

      dir() 检查名称是否在当前命名空间中定义。

      两者的组合比单独的更安全,只要您没有自己定义 copy 就可以工作。

      if ('copy' in sys.modules) and ('copy' in dir()):
      

      【讨论】:

        【解决方案5】:
        if "sys" not in dir():
          print("sys not imported!")
        

        编辑:感谢用户 vaultah。这在代码的开头(顶部)运行良好,但应谨慎使用,以防创建另一个名为 sys 的对象。

        【讨论】:

        • 只检查模块是否被导入到当前命名空间。 sys 也可以是任何东西,而不仅仅是一个模块。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-01-14
        • 2020-04-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多