[英]Python: temporarily change variable scoping rules
I was wondering if there is a trick to temporarily change the variable scoping rules in Python. 我想知道是否有一个技巧来临时更改Python中的变量范围规则。 For example, is it to possible to temporarily turn the " LEGB " rule into "LB", for debugging purposes?
例如,是否可以暂时将“ LEGB ”规则转换为“LB”,以进行调试?
The reason I'm asking is this: every now and then - especially when running stuff in (larger) ipython notebooks - a typo like the one below, doesn't become a NameError and can result in weird bugs: 我问的原因是:时不时 - 尤其是在(较大的)ipython笔记本中运行东西时 - 如下所示的拼写错误,不会成为NameError并且可能导致奇怪的错误:
def dostuff():
for i in range(3):
print j# typo
j=0
dostuff()
This can partially be addressed with static code checkers, but I thought there might be a neat trick to do this within a function?! 这可以通过静态代码检查器部分解决,但我认为在函数中可能有一个巧妙的技巧吗?!
Thanks, Andreas 谢谢,安德烈亚斯
PS: Yes, polluting namespaces makes the above more likely. PS:是的,污染名称空间使得上述更有可能。
The scoping rules of python are built into the language. python的范围规则内置于该语言中。 You can't change/disable them via any clever tricks that I can think of...
你不能通过我能想到的任何聪明的技巧来改变/禁用它们......
There are a few "best practices" that can help -- particularly when working in scripts. 有一些“最佳实践”可以提供帮助 - 特别是在脚本中工作时。 One piece of advice is to pack everything into a
main
function and call that (which helps with namespace pollution that you mentioned): 一条建议是将所有内容打包成一个
main
函数并调用它(这有助于你提到的命名空间污染):
def main():
j = 0
dostuff()
if __name__ == '__main__':
main()
But this probably doesn't help you too much when typing things out in the REPL. 但是,这可能是在REPL打字的东西出来时,不会帮助你太多 。
EDIT: While you can't change the scoping rules of the language, you can clear out the module's globals, call the function and then reset the globals after the function call. 编辑:虽然你不能改变语言的作用域规则,你可以清除模块的全局变量,调用函数,然后在函数调用后重置全局变量。 Here's a context manager that demonstrates that sort of usage:
这是一个上下文管理器,演示了这种用法:
>>> class CopyRestoreDict(object):
... def __init__(self, dct):
... self._dict = dct
... self._copy = {}
... def __enter__(self):
... self._copy.update(self._dict)
... self._dict.clear()
... def __exit__(self, *args):
... self._dict.update(self._copy)
... self._copy.clear()
...
>>> def foo():
... print j
...
>>> j = 1
>>> foo()
1
>>> with CopyRestoreDict(globals()):
... foo()
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
NameError: name 'foo' is not defined
>>> j
1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.