【问题标题】:Dynamically importing an entire module动态导入整个模块
【发布时间】:2019-05-28 20:26:49
【问题描述】:

我想知道是否有办法动态导入整个模块(相当于“import * some_module”)。

在对其他帖子进行一些研究后,我发现您可以动态执行“import some_module”,但不能拉取整个模块。

为了澄清我的问题,

一些模块:

SOME_VARIABLE = 1

模块一:

if(1 == 1):
    __import__("some_module");

模块 b:

from module a import *
print(SOME_VARIABLE);

运行此代码会返回无法识别的变量异常,我想防止这种情况发生。

动机:

假设我有一个全局模块,它通过接收参数的函数导入多个其他模块。

例子:

模块一:

import_modules(modules_id):
    if(modules_id == 1):
        from module_c import *
        from module_d import *
    else :
        from module_e import *

模块 b:

from module a import *
import_modules(1);

我想通过显式调用访问 module_c/d 中的所有变量。

我的实际问题:

我有一个接口驱动程序,它使用不同的协议(每个都通过不同的类实现)与不同的设备交互,这些协议有一定的相似之处,例如:它们都有一个 CUSTOMER_STATUS dict(在 protcol_a/b_global_def 中定义)由特定协议导入的模块)。

我遇到的问题是两个协议都有同名的变量,并且由于接口驱动程序需要识别它们,所以我不知道我从使用接口驱动程序的程序访问哪个变量(导入它) .

考虑到使用接口驱动程序的程序只能动态地知道它需要使用哪个协议,我想避免在程序中手动导入协议 global def(即使我想在程序中使用它的变量)。

【问题讨论】:

  • 显示您的代码,以便我们正确参考您的问题。
  • 我的问题并不特定于某段代码,但如果您觉得这很重要,我可以解释这样做的动机。
  • 那么你的问题没有多大意义。当然也可以动态导入。模块的一部分或整个模块,无论您选择什么。所以要么给出一个反例(在代码中),要么改写它。
  • 嘿,我已经改写了它并添加了一个示例。
  • 为什么不呢?您的代码将更加不安全,并且难以维护。但是对于python,实用性比纯度要好,所以可能会有有用的案例(我现在看不到)。

标签: python python-3.x


【解决方案1】:

这几乎可以肯定是XY problem ...但为了证明它可以做到...

假设some_module

SOME_VARIABLE = 1

将模块a设为:

globals().update(__import__("some_module").__dict__)

现在在b

from a import *
print(SOME_VARIABLE)

会产生你想要的结果。

这里发生了什么?a 中,我们导入some_module,然后获取代表其命名空间的__dict__,并使用它来更新a 中的全局变量。

【讨论】:

  • 我有globals().update(vars(__import__('module_c'))) 但是是的......这会破坏命名空间,可能会导致模块导入缓存和其他我尽量不要想太多的事情混淆。 .. 但它满足了 OP 的要求——即使像你一样我强烈同意这可能是一个 XY 问题:)
  • 恐怕这两种解决方案都不适合我。生病解释我试图做什么,以将其清除为 XY 问题。
  • 我已经更新了帖子以包含我的实际问题,我希望它足够澄清,如果不告诉我并且我会尝试改写。提前谢谢。
【解决方案2】:

模块一个

exec('from some_module import *')

模块 b

import importlib
a=importlib.import_module('module a')
for i in dir(a):
    if not i.startswith('_'):
        exec('{0}=a.{0}'.format(i))
print(SOME_VARIABLE);

【讨论】:

  • 这不是我想要的,我重新编辑了这个问题以便更好地理解这个问题。
  • 看到我想让模块 a 为模块 b 导入,这是行不通的。
  • @Rohi 你得到了什么
  • 我应该更清楚地说明,这并不是说它不起作用,而是它没有解决我的问题。我想要模块 b,只导入模块 a,并让模块 a 为模块 b 导入其他所有内容(不在模块 b 中添加额外的逻辑)。
  • @Rohi 是否需要在模块名称中包含空格
【解决方案3】:

扩展至donkopotamus的答案

使模块成为一个:

def load_module():
    globals().update(__import__("some_module").__dict__)

现在在b

from a import *
load_module()
from a import *
print(SOME_VARIABLE)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-25
    • 2011-04-17
    • 2023-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-13
    • 1970-01-01
    相关资源
    最近更新 更多