是否可以将模块注入导入模块的全局变量?

时间:2016-12-06 21:15:52

标签: python

我有一个文件hello.py,其函数为hello()

hello.py

def hello():
    print "hello world"

我有另一个文件test.py导入hello,并调用该函数。

test.py

from hello import *

def run():
    hello()

if __name__ == '__main__':
    run()

如果我通过python运行test.py,它按预期工作:

$ python test.py
hello world

但是,我现在编辑test.py删除导入语句

test.py

def run():
    hello()    # hello is obviously not in scope here

if __name__ == '__main__':
    run()

我介绍第3个文件run.py导入hello.pytest.py

run.py

from hello import *
from test import *

if __name__ == '__main__':
    run()

当然这不起作用,因为hello()不在test.py's范围内。

$ python run.py 
Traceback (most recent call last):
  File "run.py", line 5, in <module>
    run()
  File "test.py", line 4, in run
    hello()
NameError: global name 'hello' is not defined

问题:

  • 是否可以<{em>} hello() test.py's来自run.py的{​​{1}}范围,,而run.py导入hello.py

我很高兴使用较低级别的功能,例如imp模块,如果这是必需的。

3 个答案:

答案 0 :(得分:3)

是。模块的属性它的全局变量,所以你可以在那里戳它。

import test
import hello
test.hello = hello.hello

我将重申wim的评论,这通常不是一个好主意。

答案 1 :(得分:2)

模块是可变的:

import hello
import test

test.hello = hello.hello

if __name__ == '__main__':
    test.run()

答案 2 :(得分:0)

你所描述的内容听起来像一个类。如果它像一个类一样走路,它就像一个类,它就是一个类。

hello.py

class Hello(object):
    @classmethod
    def hello(class_):
        print("Hello, world!")

test.py

class Test(object):
    @classmethod
    def run(class_):
        class_.hello()

run.py

import hello
import test

class Run(hello.Hello, test.Test):
    pass

if __name__ == '__main__':
    # Note: we don't instantiate the class.
    Run.run()

这并没有给出完全相同的语法,因此它不能直接回答您的问题,但它提供了您正在寻找的相同功能,而无需诉诸意外的黑客攻击,例如修改其他模块。

我所描述的并不是唯一的方法来解决这个问题,但让一个模块修改另一个模块对于您的代码来说可能是一种相当令人惊讶的方式。