在模块名称空间中替换自身的Python函数

在模块名称空间中替换自身的Python函数,python,Python,我正在阅读Werkzeug的一些资料,在Werkzeug.wrappers模块中偶然发现了这个金块 def _run_wsgi_app(*args): """This function replaces itself to ensure that the test module is not imported unless required. DO NOT USE! """ global _run_wsgi_app from werkzeug.test

我正在阅读Werkzeug的一些资料,在Werkzeug.wrappers模块中偶然发现了这个金块

def _run_wsgi_app(*args):
    """This function replaces itself to ensure that the test module is not
    imported unless required.  DO NOT USE!
    """
    global _run_wsgi_app
    from werkzeug.test import run_wsgi_app as _run_wsgi_app
    return _run_wsgi_app(*args)

这样做有什么好处?此定义与另一个没有
global\u run\u wsgi\u app
语句的定义有什么区别?

如果没有
global
语句,您将创建一个名为
\u run\u wsgi\u app
的局部变量,然后使用它,但全局名称空间中不会有任何更改。使用
global\u run\u wsgi\u app
可确保将全局名称重新绑定到新函数

记住
global
的基本用法:

def foo():
    x = 2
def bar():
    global x
    x = 3

x = 1
print(x) # --> 1
foo()
print(x) # --> 1
bar()
print(x) # --> 3
您的示例与此相同,但它不是直接使用
name=…
绑定名称,而是使用
from。。。导入。。。作为名称

在不使用
全局
的情况下重新定义自身的另一种方法是使用包含它的模块对象

def _run_wsgi_app(*args):
    from werkzeug.test import run_wsgi_app as new_run_wsgi_app
    import sys
    sys.modules[__name__]._run_wsgi_app = new_run_wsgi_app
    return new_run_wsgi_app(*args)

import
语句也绑定到一个名称;在该函数中,来自werkzeug.test import run_wsgi_app as_run_wsgi_app的
将绑定到本地名称,但使导入绑定为全局名称的
全局
除外。