简体   繁体   English

Python从模块变量导入

[英]Python import from module variable

I have a package that contains a module with compatible imports. 我有一个包含包含兼容进口模块的包装。 However, I cannot import from the exposed modules directly; 但是,我无法直接从公开的模块中导入。 I have to use slightly more inconvenient workarounds. 我不得不使用稍微不便的解决方法。

Inside common/compat.py, I have this: 在common / compat.py中,我有这个:

import bcrypt

In main.py, this does not work: 在main.py中,这不起作用:

from common.compat.bcrypt import hashpw

with the error: 与错误:

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

However, this works fine: 但是,这很好用:

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

Is there any way to make the first one work properly without having to do the second solution? 有什么方法可以使第一个解决方案正常工作而无需执行第二个解决方案? I would prefer from imports for quite a few classes and methods. 我希望从导入中获取很多类和方法。

The problem is that bcrypt is not actually a submodule of common.compat ; 问题在于bcrypt实际上不是common.compat的子模块; the module object is actually a member attribute of the common.compat module object with the name bcrypt within common.compat 's namespace. 模块对象实际上是成员属性common.compat具有名称模块对象bcryptcommon.compat的命名空间。 As a consequence, if you want to be able to import bcrypt as if it is a submodule of common.compat as opposed to a value from its namespace, you need to monkey around a bit. 结果,如果您希望能够将bcrypt当作是common.compat的子模块(而不是其命名空间中的值)导入,则需要花点时间。 You could create a dummy bcrypt module within your package structure then from bcrypt import * inside it to alias it, but probably the better way would be to directly modify sys.modules in compat.py . 您可以在包结构中创建一个虚拟bcrypt模块,然后from bcrypt import *对其进行别名,但是更好的方法可能是直接在compat.py修改sys.modules

import sys
import bcrypt

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

As commenters have noted though, modifying sys.modules is dangerous. 正如评论者所指出的那样,修改sys.modules是危险的。 I'm inferring from the fact that you call your package common.compat that you are creating some sort of compatibility module that implements fallback logic in case some dependency is not available. 我从您将包称为common.compat的事实推断出,您正在创建某种兼容模块,该模块将在没有相关性的情况下实现回退逻辑。 Instead of hacking sys.modules , you'll likely be better served creating a common.compat.crypto module that looks something like 与其破解sys.modules ,不如创建一个common.compat.crypto模块,它看起来像是更好的选择。

try:
    from bcrypt import hashpw
except ImportError:
    # Alternative import, hand-written alternative,
    # or function that raises NotImplementedError here

Then in your main.py , just from common.compat.crypto import hashpw . 然后在main.py ,仅从from common.compat.crypto import hashpw

Would the following be what you are looking for ? 以下是您要寻找的东西吗?

from common.compat import bcrypt.hashpw

However, it seems a bad idea to build depedencies in such way, because you don't seem to need that compat.py even exist to get your bcrypt module. 但是,以这种方式构建虚拟对象似乎不是一个好主意,因为您似乎甚至不需要compat.py来获取bcrypt模块。 Thus I would rather do one of the following : 因此,我宁愿执行以下操作之一:

  1. Import bcrypt.hashpw in main.py, as a direct dependency 将bcrypt.hashpw导入main.py中,作为直接依赖项
  2. Import bcrypt from the common/compat.py script like you suggest in your last snippet 像您在上一小段中建议的那样,从common / compat.py脚本导入bcrypt
  3. Do something with hashpw in common/compat.py (eg subclassing or wrapping), and import the subclass/wrapper from compat.py in main.py 在common / compat.py中对hashpw进行处理(例如,子类化或包装),并从main.py中的compat.py导入子类/包装器

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

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