在C ++中,您可以这样做以强制本地范围:
{
int i = 1;
// Do stuff
}
// local variable i is destroyed
{
int i = 7;
// Do more stuff
}
这样做的好处是,在强制本地范围结束时,括号中声明的任何变量都消失了。这有助于防止在以后您不打算使用x的位置使用先前定义的变量x。
你能用Python做到这一点吗?如果是这样,怎么样?
== UPDATE ==
我知道功能 - 这是显而易见的事情。我想知道当代码很简单并且不值得创建单独的函数时,是否有一种快速的方法来执行上述操作 - 只需要一些快速符号来强调此块中的变量不会在其他任何地方使用功能。
到目前为止,人们所说的简短回答是否定的。
(我知道有一些聪明的方法,比如“del”,或者这种有块的愿望可能会建议重构成一个单独的函数。但是我想强调这只是为了简短的片段你要强调的这个小块中的变量不能在别处使用。)
答案 0 :(得分:7)
在Python中,如果在函数内部声明变量,则它是本地的,不能在函数外部访问
>>> def x():
i = 5
>>> x()
>>> i
Traceback (most recent call last):
File "<pyshell#5>", line 1, in <module>
i
NameError: name 'i' is not defined
>>>
或者,您可以从末尾的命名空间中删除该变量,以便您不能重复使用它。
>>> i = 5
>>> del i
>>> i
Traceback (most recent call last):
File "<pyshell#8>", line 1, in <module>
i
NameError: name 'i' is not defined
>>>
答案 1 :(得分:1)
如果您不喜欢del
解决方案,可以嵌套函数定义:
def one_function():
x=0
def f():
x = 1
f()
print(x) # 0
当然,我认为更好的方法是将事物分成更小的函数,因此不需要这个手动范围。在C ++中,关于它的最酷的事情就是自动调用析构函数 - 在Python中,你不能真正保证析构函数将被调用,所以即使可能,这个作用域也不会非常有用。
答案 2 :(得分:1)
在C ++中,您使用带括号{}
的本地范围来避免变量重定义或命名冲突:
{
int var=3;
}
{
float var=1.0f;
}
在python中,没有显式变量 definition ,只需在想要使用它时将一些对象分配给var名称,并将相同名称重新绑定到一些新变量:
var=3
#do something
var=1.0 #no need to "del var", var refers to a float object now
#do more stuff
注意在C ++中使用范围块可能表明您的代码需要重构为可以命名和重用的函数或方法。和python一样。
答案 3 :(得分:0)
我有同样的问题,发现您绝对可以!
它不像c样式块那么干净,但是通过两次python怪癖,我们可以使其达到我们的目的。
怪癖:
这是您的示例:
class DoStuff:
i = 1
# Do stuff
# local variable i is destroyed
class DoStuff:
i = 7
# Do more stuff
# local variable i is destroyed
要在此处充分体现灵活性,请参见以下示例。我将类命名为“ Scope”,因为这可能是我将其与其他命名类区分开的名称。 注意,“范围”当然可以是任何东西。
我建议您在整个项目中使用一个名称,并将该名称添加到您的文档中,以便使您理解这是一个永远不应实例化的特殊名称。
outer = 1
class Scope:
inner = outer
print("runs first ---")
print("outer %d" % outer)
print("inner %d" % inner)
class Scope:
inner = outer + 1
print("runs second ---")
print("outer %d" % outer)
print("inner %d" % inner)
print("runs last ---")
print("outer %d" % outer)
print("inner %d" % inner) # This will give an error. Inner does not exist in this scope!
输出:
runs first ---
outer 1
inner 1
runs second ---
outer 1
inner 2
runs last ---
outer 1
Traceback (most recent call last):
File "test.py", line 18, in <module>
print("inner %d" % inner) # This will give an error. Inner does not exist in this scope!
NameError: name 'inner' is not defined
这是可行的-让我们看一下好处/缺点的权衡。
好处:
缺点:
对于所有您想限制范围的代码,我认为这都是值得的,但没有太多使用该代码的地方,或者尚不清楚如何编写通用函数来解决所有这些情况。
如果阅读此书的人感到还有其他权衡的问题,请在此处评论,我将确保它们在“缺点”部分中有代表。
有关此公约的更多讨论,John Carmack,Jonathan Blow和Casey Muratori首选。
答案 4 :(得分:0)
我已承诺用诡计解决这个问题。
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)
https://github.com/l74d/scoping
顺便说一下,我发现dummy class的解决方案可能会导致内存泄漏。例如,在被覆盖的类中创建的大型 numpy 数组似乎没有通过查看内存统计信息进行垃圾收集,但这可能是一个实现相关的事情。