简体   繁体   English

如何检查python模块是否已导入?

[英]How to check if a python module has been imported?

How do I check if I imported a module somewhere in the code?如何检查我是否在代码中的某处导入了模块?

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

The reason that I would like to check if I already imported a module is because I have a module that I don't want to import because sometimes it messes up my program.我想检查是否已经导入了一个模块的原因是因为我有一个不想导入的模块,因为有时它会弄乱我的程序。

Test for the module name in the sys.modules dictionary :sys.modules字典中测试模块名称:

import sys

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

From the documenation:从文档中:

This is a dictionary that maps module names to modules which have already been loaded.这是一个将模块名称映射到已加载模块的字典。

Note that an import statement does two things:请注意, import语句会做两件事:

  1. if the module has never been imported before (== not present in sys.modules ), then it is loaded and added to sys.modules .如果模块之前从未导入过(== 不存在于sys.modules ),则将其加载并添加到sys.modules
  2. Bind 1 or more names in the current namespace that reference the module object or to objects that are members of the module namespace.将当前命名空间中的 1 个或多个名称绑定到引用模块对象或作为模块命名空间成员的对象。

The expression modulename not in sys.modules tests if step 1 has taken place. modulename not in sys.modules的表达式modulename not in sys.modules测试步骤 1 是否已经发生。 Testing for the result of step 2 requires knowing what exact import statement was used as they set different names to reference different objects:测试第 2 步的结果需要知道使用了什么确切的import语句,因为它们设置了不同的名称来引用不同的对象:

  • import modulename sets modulename = sys.modules['modulename'] import modulename设置modulename = sys.modules['modulename']
  • import packagename.nestedmodule sets packagename = sys.modules['packagename'] (no matter how many addional levels you add) import packagename.nestedmodule sets packagename = sys.modules['packagename'] (不管你添加了多少附加级别)
  • import modulename as altname sets altname = sys.module['modulename'] import modulename as altname设置altname = sys.module['modulename']
  • import packagename.nestedmodule as altname sets altname = sys.modules['packagename.nestedmodule'] import packagename.nestedmodule as altname set altname = sys.modules['packagename.nestedmodule']
  • from somemodule import objectname sets objectname = sys.modules['somemodule'].objectname from somemodule import objectname设置objectname = sys.modules['somemodule'].objectname
  • from packagename import nestedmodulename sets nestedmodulename = sys.modules['packagename.nestedmodulename'] (only when there was no object named nestedmodulename in the packagename namespace before this import, an additional name for the nested module is added to the parent package namespace at this point) from packagename import nestedmodulename sets nestedmodulename = sys.modules['packagename.nestedmodulename'] (仅当在此导入之前packagename命名空间中没有名为nestedmodulename对象时,嵌套模块的附加名称会添加到父包命名空间中)观点)
  • from somemodule import objectname as altname sets altname = sys.modules['somemodule'].objectname from somemodule import objectname as altname sets altname = sys.modules['somemodule'].objectname
  • from packagename import nestedmodulename as altname sets altname = sys.modules['packagename.nestedmodulename'] (only when there was no object named nestedmodulename in the packagename namespace before this import, an additional name for the nested module is added to the parent package namespace at this point) from packagename import nestedmodulename as altname sets altname = sys.modules['packagename.nestedmodulename'] (仅当在此导入之前packagename命名空间中没有名为nestedmodulename对象时,嵌套模块的附加名称被添加到父包命名空间这一点)

You can test if the name to which the imported object was bound exists in a given namespace:您可以测试导入对象绑定的名称是否存在于给定的命名空间中:

# 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'])

This only tells you of the name exists (has been bound), not if it refers to a specific module or object from that module.这只会告诉您名称存在(已绑定),而不是它是否引用特定模块或来自该模块的对象。 You could further introspect that object or test if it's the same object as what's available in sys.modules , if you need to rule out that the name has been set to something else entirely since then.您可以进一步内省该对象或测试它是否与sys.modules可用的对象相同,如果您需要排除该名称从那时起已完全设置为其他内容。

To the sys.modules answers accepted, I'd add one caveat to be careful about renaming modules on import:对于接受的 sys.modules 答案,我会添加一个警告,以注意在导入时重命名模块:

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

use sys.modules to test if a module has been imported (I'm using unicodedata as an example):使用 sys.modules 测试模块是否已导入(我以 unicodedata 为例):

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

sys.modules contains all modules used anywhere in the current instance of the interpreter and so shows up if imported in any other Python module. sys.modules包含解释器当前实例中任何地方使用的所有模块,因此如果在任何其他 Python 模块中导入,则会显示。

dir() checks whether the name was defined in the current namespace. dir()检查名称是否在当前命名空间中定义。

The combination of the 2 is more safe than each separate and works as long you didn't define a copy yourself. 2 的组合比单独的更安全,只要您没有自己定义copy

if ('copy' in sys.modules) and ('copy' in dir()):
if "sys" not in dir():
  print("sys not imported!")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM