Python从模块变量导入

时间:2014-02-18 19:36:58

标签: python import

我有一个包含兼容导入模块的包。但是,我不能直接从暴露的模块导入;我必须使用稍微不方便的解决方法。

在common / compat.py中,我有这个:

import bcrypt

在main.py中,这不起作用:

from common.compat.bcrypt import hashpw

错误:

Traceback (most recent call last):
  File "main.py", line 2, in <module>
    from common.compat.bcrypt import hashpw
ImportError: No module named bcrypt

然而,这很好用:

from common.compat import bcrypt
# now bcrypt.hashpw works fine

有没有办法让第一个工作正常而不必做第二个解决方案?我更喜欢从很多类和方法的导入。

2 个答案:

答案 0 :(得分:1)

问题是bcrypt实际上不是common.compat的子模块;模块对象实际上是common.compat模块对象的成员属性,在bcrypt的命名空间中名称为common.compat。因此,如果您希望能够导入bcrypt,就好像它是common.compat的子模块而不是其命名空间中的值,您需要稍微改变一下。您可以在包结构中创建一个虚拟bcrypt模块,然后在其中添加from bcrypt import *以对其进行别名,但最好的方法是直接修改sys.modules中的compat.py。< / p>

import sys
import bcrypt

sys.modules['common.compat.bcrypt'] = bcrypt

正如评论者所指出的那样,修改sys.modules是危险的。我推断你调用你的软件包common.compat你正在创建某种兼容性模块,以便在某些依赖项不可用的情况下实现回退逻辑。而不是攻击sys.modules,您可能会更好地创建一个类似于

common.compat.crypto模块
try:
    from bcrypt import hashpw
except ImportError:
    # Alternative import, hand-written alternative,
    # or function that raises NotImplementedError here

然后在main.pyfrom common.compat.crypto import hashpw

答案 1 :(得分:0)

以下是您想要的吗?

from common.compat import bcrypt.hashpw

但是,以这种方式构建依赖关系似乎是一个坏主意,因为您似乎不需要compat.py来获取您的bcrypt模块。因此,我宁愿做以下其中一项:

  1. 在main.py中导入bcrypt.hashpw,作为直接依赖
  2. 从您在上一个代码段
  3. 中建议的common / compat.py脚本导入bcrypt
  4. 使用hashpw in common / compat.py(例如子类或包装)执行某些操作,并从main.py中的compat.py导入子类/包装器