在C和变体中,当您遇到类似这样的情况时:
{
tmp1 <- 5
tmp2 <- 2
print(tmp1 + tmp2)
}
将打印出7,但是一旦范围tmp1
结束,tmp2
和}
变量将从堆栈中删除。有时我希望在python中使用类似的功能,这样我就不必在某个时间点后清理(许多)临时变量。
在R中,您可以使用local({insert piece of code})
来实现此目的。
我们如何在python中获得相似但可读的行为?
答案 0 :(得分:2)
没有任何特殊的语法,但是您可以通过手动删除变量来实现类似的目的:
tmp1 = 5
tmp2 = 2
print(tmp1 + tmp2)
del tmp1
del tmp2
如果您不喜欢这种语法,则可以使用:
def local(f):
f()
@local
def block():
tmp1 = 5
tmp2 = 2
print(tmp1 + tmp2)
基本上与:
def block():
...
local(block)
(https://hackernoon.com/decorators-in-python-8fd0dce93c08)
但是,这一点确实很简单。
答案 1 :(得分:1)
实际上,您可以实现一些棘手的模拟操作。
import inspect
from contextlib import contextmanager
@contextmanager
def Local():
enter_locals = set(inspect.currentframe().f_back.f_back.f_locals.keys())
yield
exit_locals = set(inspect.currentframe().f_back.f_back.f_locals.keys())
substract = exit_locals - enter_locals
for variable in substract:
del inspect.currentframe().f_back.f_back.f_locals[variable]
with Local():
a = 1
b = 2
print(a + b)
print(a + b)
# 3
# ...
# ----> 6 print(a + b)
#
# NameError: name 'a' is not defined
但实际上不建议这样做。为什么要用Python模拟其他语言? Python是Python,没有块范围,也没有块范围。
答案 2 :(得分:1)
最终确定一个工程解决方案,您仍然可以故意泄漏选定的变量。
from scoping import scoping
a = 2
with scoping():
assert(2 == a)
a = 3
b = 4
scoping.keep('b')
assert(3 == a)
assert(2 == a)
assert(4 == b)
答案 3 :(得分:0)
请参见https://stackoverflow.com/a/292502/51685,以了解Python可变作用域规则的细致之处。
存在范围的变量将自动清除,但是您也可以使用del
关键字删除对它们的引用。
very_large_data = 'x' * 1_000_000_000 # a gigabyte of x!
# do things...
del very_large_data # that gigabyte will be garbage-collected soon after
如果您担心使调试等操作变得容易的“范围污染”,只需将代码重构为较小的函数和/或类(以便可以将共享状态保存在self.
中)
答案 4 :(得分:0)
来自What's the scope of a variable initialized in an if statement?
Python变量的作用域是分配给它们的最里面的函数,类或模块。控制块(如if和while块)不计在内,因此在if内分配的变量的作用域仍然是函数,类或模块。
因此,如果您想知道这为何起作用:
for i in range(0, 3):
a = i
print(a)
>> 2
,为什么a
可以在for循环之外访问,那么答案是python
而不是c++
或R
。删除它们将是一种非Python的方法,但是您可以通过查看其他答案来明确地这样做