【发布时间】: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_back、gc.get_referents、ctypes 或来自更强大但更可怕的标准库之一的其他工具?
【问题讨论】:
-
为什么要这样做?无论您有什么基本目标,都可能有更好的方法来实现它。
-
@user2357112 我想防止从函数中引用的全局变量被隐藏。
print和str之类的东西 -
什么,又是那个?看,如果你不小心踩到了你的全局变量,那就是一个错误。您尝试应用的任何技术变通方法都无法使您不必修复错误。您尝试使用的任何替换全局命名空间都可以像原始命名空间一样容易或更容易搞砸。增加复杂性只是意味着你有更多的机会搞砸,一旦事情破裂,就更难理解出了什么问题。
-
无论如何,即使控制
foo的全局命名空间可以解决您的问题,从一开始就在受控命名空间中创建foo比尝试设置事后命名空间。您可以使用exec来做到这一点,或者只是将foo粘贴在它自己的模块中。
标签: python python-3.x globals