我有一个包含兼容导入模块的包。但是,我不能直接从暴露的模块导入;我必须使用稍微不方便的解决方法。
在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
有没有办法让第一个工作正常而不必做第二个解决方案?我更喜欢从很多类和方法的导入。
答案 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.py
,from common.compat.crypto import hashpw
。
答案 1 :(得分:0)
以下是您想要的吗?
from common.compat import bcrypt.hashpw
但是,以这种方式构建依赖关系似乎是一个坏主意,因为您似乎不需要compat.py来获取您的bcrypt模块。因此,我宁愿做以下其中一项: