【问题标题】:Why would you execute code in a local scope just to update the global scope?为什么要在本地范围内执行代码只是为了更新全局范围?
【发布时间】:2018-07-18 16:06:38
【问题描述】:

pkg_resources 模块中你有这个奇怪的功能:

@_call_aside
def _initialize_master_working_set():
    # A bunch of ugly code, and then finally:
    globals().update(locals())

_call_aside 是这样定义的装饰器,它在定义时调用一次函数(为什么要使用装饰器而不是简单地显式调用函数,我不知道):

def _call_aside(f, *args, **kwargs):
    f(*args, **kwargs)
    return f

函数_initialize_master_working_set 没有在其他任何地方调用,名称上的下划线表明它不打算供公众重复使用。文档字符串进一步警告不要调用:

此函数...旨在在此模块初始化时调用一次。 不支持其他包调用

我不明白。这不只是在模块范围内执行“一堆丑陋的代码”的一种混淆方式吗?这种模式与直接在全局范围内执行代码有何不同?

【问题讨论】:

  • 我的猜测是提供可以多次调用以进行测试的东西。 (看起来测试并没有特别好地利用这个机会,但它就在那里。)

标签: python setuptools pkg-resources


【解决方案1】:

Git blame 出现了一个 commit message 和一个指向 issue 的链接,这促使了这个函数的引入。有人想要一种方法来重新运行这个初始化,所以他们把它提取到一个可以重复调用的函数中。

此函数的行为与旧版本没有任何不同,旧版本的代码处于模块级别。虽然在某些情况下,末尾带有 globals().update(locals()) 的函数的行为与直接在全局范围内运行代码的行为不同(例如,如果其他东西在函数中间重新绑定相同的全局名称,则函数将踩踏最后的那些变化),这不是引入这个功能的动机。他们只是希望能够按需重新运行。

【讨论】:

    猜你喜欢
    • 2021-04-30
    • 1970-01-01
    • 2021-03-05
    • 2013-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多