【问题标题】:Is there some way to manually set the global namespace for a particulair function?有没有办法手动设置特定函数的全局命名空间?
【发布时间】:2020-02-23 08:11:05
【问题描述】:

我们正在下面的伪代码中寻找set_globals 的实现:

def foo():
    """
    GLOBALS: `str`, `print`
    """
    print('apples', 'do I exist?')
    print(str('apples'))

foo_dot_globals = {'print':print, 'str':str, 'globby':1}
# set_globals(foo, foo_dot_globals)

#############################################
#  END OF DEFINING `foo`
#  BEGIN MESSING UP GLOBALS
#############################################

import sys
def print(*args, end="\n", file=sys.stdout, print=print):
    print("SIKE!", type(args[0]), args[0], file=file, end=end)

str = lambda s, *, str=str:\
    int(str(s).lower(), 36)

#############################################
#  END MESSING UP GLOBALS. BEGIN CALLING foo()
#############################################

foo()

期望的输出:

apples do I exist?
apples

当前输出:

SIKE! <class 'str'> apples
SIKE! <class 'int'> 647846308

想法:

也许我们可以结合使用inspect.currentframe().f_backgc.get_referentsctypes 或来自更强大但更可怕的标准库之一的其他工具?

【问题讨论】:

  • 为什么要这样做?无论您有什么基本目标,都可能有更好的方法来实现它。
  • @user2357112 我想防止从函数中引用的全局变量被隐藏。 printstr 之类的东西
  • 什么,又是那个?看,如果你不小心踩到了你的全局变量,那就是一个错误。您尝试应用的任何技术变通方法都无法使您不必修复错误。您尝试使用的任何替换全局命名空间都可以像原始命名空间一样容易或更容易搞砸。增加复杂性只是意味着你有更多的机会搞砸,一旦事情破裂,就更难理解出了什么问题。
  • 无论如何,即使控制foo 的全局命名空间可以解决您的问题,从一开始就在受控命名空间中创建foo 比尝试设置事后命名空间。您可以使用exec 来做到这一点,或者只是将foo 粘贴在它自己的模块中。

标签: python python-3.x globals


【解决方案1】:

你可以像这样劫持函数对象的全局命名空间:

>>> exec(foo.__code__, foo_dot_globals)
apples do I exist?
apples

【讨论】:

  • 这依赖于没有参数或闭包变量的函数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-06
  • 1970-01-01
  • 2010-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-19
相关资源
最近更新 更多