【问题标题】:Is there a way for a module or package being imported to reference a variable defined in the module (script) that does importing?有没有办法让被导入的模块或包引用在导入的模块(脚本)中定义的变量?
【发布时间】:2021-11-30 12:18:31
【问题描述】:

基本上,例如,我可以使用正在导入的模块中定义的函数来打印在执行导入的脚本中定义的全局变量x 吗?下面,我描述了一个类似的问题,但更适合我的具体任务。

结构

.
├── main.py
└── pkg
    ├── __init__.py
    └── a.py

main.py

from pkg.a import f
global_var = 10
f()

pkg/a.py

def f():
    print(global_var)

期望的输出:

$ python3 main.py
10

【问题讨论】:

  • 也许您想从f 中调查globals()

标签: python python-import


【解决方案1】:

您可以检查globals() 返回的字典中的内容。但是你必须弄清楚你感兴趣的是什么:

a=2
for key in list(globals().keys()):
    if not key.startswith('_'):  # make sure to define your rules properly here
        print(key, globals().get(key, 'my_default_if_vanished'))

我的(过滤后的)输出是:

exit <IPython.core.autocall.ExitAutocall object at 0x000002A9CAE3D700>
quit <IPython.core.autocall.ExitAutocall object at 0x000002A9CAE3D700>
sys <module 'sys' (built-in)>
a 2

请注意,由于全局变量可能会在您第一次查看它的确切时刻和您尝试访问某些信息的时刻之间发生变化,因此不建议直接迭代其键(我制作了键的“快照”进入一个列表,然后尝试获取该键的值,否则返回一个有意义的默认值)。

您可能需要查看this 问题以了解更多信息。

编辑 以上并没有真正回答OP的问题。同样根据globals()上的文档:

返回一个表示当前全局符号表的字典。这始终是当前模块的字典(在函数或方法中,这是定义它的模块,而不是调用它的模块)。

因此,我的建议是保留一个由任何导入的包/模块维护的全局注册表:

.
├── main.py
├── globals.py  (with some meaningful var? Maybe `my_globs: dict = {}`
└── pkg
    ├── __init__.py  -> updates `my_globs`
    └── a.py  -> updates and uses `my_globs`

或者也许通过装饰有针对性的和更密集的维护编码:

.
├── main.py
└── pkg
    ├── __init__.py
    └── a.py

main.py:

from pkg.a import f, pass_globals_on, print_obj_lvl_glob_reg
glob_in_project_main = "YES WE CAN"
f = pass_globals_on(f, globs=globals())
print_obj_lvl_glob_reg(f)

pkg.__init__.py

glob_in_funcs_init = __file__

pkg.a.py:

glob_in_funcs = __file__


def f():
    pass


def pass_globals_on(f, *, globs):
    d = {**globals(), **globs}
    setattr(f, 'obj_lvl_glob_reg', d)
    return f


def print_obj_lvl_glob_reg(f):
    try:
        d = getattr(f, 'obj_lvl_glob_reg')
        for key in list(d.keys()):
            if not key.startswith('_'):  # make sure to define your rules properly here
                print(key, d.get(key, 'my_default_if_vanished'))
    except AttributeError:
        pass

输出(过滤):

glob_in_funcs <path_to_proj>\pkg\a.py
f <function f at 0x0000025CB30A0670>
pass_globals_on <function pass_globals_on at 0x0000025CB30A0820>
print_obj_lvl_glob_reg <function print_obj_lvl_glob_reg at 0x0000025CB30A08B0>
glob_in_project_main YES WE CAN

【讨论】:

  • 谢谢,但您从定义a 的同一模块调用globals()!虽然我要问的是如何使变量可用于某些导入的模块
  • 应该以同样的方式工作。在您自己的 f() 函数中尝试 for 循环。
  • 嗯...真的无法完成这项工作。尝试导入模块并在不同的时间调用globals() - 没有。我一直将输出保存到文件中,找不到与变量相关的任何内容。也许,你可以分享你的代码?
  • 你是对的。我更新了我的答案。
  • 谢谢!现在,我最终使用了环境变量,而不是在 Python 模块中定义变量。但我一定会研究你的答案
猜你喜欢
  • 2021-10-15
  • 2017-06-12
  • 1970-01-01
  • 2021-12-10
  • 2013-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-14
相关资源
最近更新 更多