如何用hasattr检查Python子模块

0 投票
3 回答
3141 浏览
提问于 2025-04-16 01:13

在运行时,Python代码需要加载一个子模块的名字,而这个名字我事先并不知道。现在,我想检查一下,这个子模块是否存在于一个已经存在的模块里。考虑一下这个结构,其中可以指定foobar

master/
|
|- __init__.py
|
|- foo/
|  |
|  |- __init__.py
|
|- bar/
   |
   |- __init__.py

通常,我会这样做,这对函数和变量是有效的:

import master

unknown_submodule = "foo"
if hasattr(master, unknown_submodule):
    pass # all's well

或者我会捕获AttributeError,这样也能工作。

但是,按照上面的文件结构,我无法让这种方法正常工作。hasattr()总是返回False(也就是说,总是会抛出AttributeError)。

如果我查看dir(master),我看到的输出是:

['__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__']

即使在master/__init__.py中明确指定__all__也没有帮助,但会把dir()的结果改成:

['__all__', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__']

有没有人知道我哪里做错了,或者有没有办法实现这些测试?(顺便说一下:我在Win/Cygwin上使用Python 2.6,如果这有帮助的话)

3 个回答

1

你可以这样做:

try:
 import module.submodule

except ImportError:
  print 'failed or whatever'
2

我最近需要检查一个子模块是否存在,因为我使用的是Python 3.4.1,所以我给这个问题提供了一个新的答案:

在Python 3.4.1中,你可以使用 importlib.util.find_spec(name, package=None) 来做到这一点。你可以在这里查看详细信息:https://docs.python.org/3.4/library/importlib.html#importlib.util.find_spec

import importlib
module_exists = importlib.util.find_spec('path.to.my.module')

就这么简单 =)

2

子模块并不是它们父模块的属性,除非明确说明。你可以尝试导入这个模块,如果导入失败,就会捕捉到一个叫做 ImportError 的错误。

try:
    __import__("os.peth", fromlist=[os])
except ImportError:
    pass

撰写回答