简体   繁体   English

Python:暂时更改变量范围规则

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM