【发布时间】:2020-12-26 01:06:42
【问题描述】:
为了好玩,我正在尝试在 Python 中实现类似于 block scoping 的东西。这就是我得出的结论:
import inspect
class Scope:
def __init__(self, *args):
self._start = inspect.currentframe().f_back.f_locals.copy()
print(self._start)
def __enter__(self, *args):
pass
def __exit__(self, *args):
for name in inspect.currentframe().f_back.f_locals.copy():
if name not in self._start:
print(f"deleting {name}")
# print(globals())
# del globals()[name]
del inspect.currentframe().f_back.f_locals[name] # this doesn't do anything
print(inspect.currentframe().f_back.f_locals) # no change
def compute(foo):
with Scope():
bar = foo ** 2
print(bar)
return bar # this should fail
compute(5)
不幸的是,当前帧以外的帧似乎无法修改。 (可能有充分的理由?:P)。我也尝试过修改globals dict 并且可行,但仅适用于创建的词法范围位于模块级别的情况。我希望我的解决方案能够在函数等内部工作。
我尝试使用with API 来模仿其他语言的作用域。我很高兴听到使用可能有效的不同技术的解决方案。
TLDR:我想要某种构造,在退出时自动销毁绑定在其中的所有局部变量。
【问题讨论】:
-
@juanpa.arrivillaga 嗯,Python 名称解析不是在运行时有效吗?这算作词法作用域吗?在任何一种情况下,我想要做的基本上是创建“作用域”,在退出时破坏局部变量。
-
@juanpa.arrivillaga 谢谢,已编辑。
-
无论如何,如果不认真破解运行时内部结构,这将很难。
del inspect.currentframe().f_back.f_locals[name]不起作用,Python 不支持动态修改局部变量,即locals()['x'] = 'foo'实际上不会影响本地命名空间 -
如果你得到这个工作,你一定要写一个答案
-
不确定您当前的方法,因为它似乎首先尝试对 python 代码的解释方式进行一些非常深刻的更改,但是实现块作用域的一种更简单(但丑陋)的方法可能是使用元类来创建类,这些类在创建时执行 init 函数中的任何代码,然后删除它们自己。 (我的意思是这将是一个丑陋的黑客,但既然你只是为了好玩,你可能会从中学到很多东西哈哈)