在Python中阻止范围

Joh*_*åde 85 python scope

当您使用其他语言编写代码时,有时会创建一个块范围,如下所示:

statement
...
statement
{
    statement
    ...
    statement
}
statement
...
statement
Run Code Online (Sandbox Code Playgroud)

一个目的(很多)是提高代码可读性:显示某些语句形成逻辑单元或某些局部变量仅在该块中使用.

是否有一种在Python中做同样事情的惯用方法?

Tho*_*asH 70

不,没有语言支持来创建块范围.创建范围的唯一方法是函数,类或模块.

  • 尽管有标题和问题的字面部分,但我认为问题实际上更多的是关于*分组*而不是*范围*(限制/隐藏变量)。`if True` 构造达到了预期的效果(但是 [Pylint](https://en.wikipedia.org/wiki/Pylint) 会抱怨 *"W0125: 使用具有常量值的条件语句 (using-constant-测试)”*) (2认同)

Sve*_*ach 36

Python中惯用的方法是保持你的功能简短.如果您认为需要这个,请重构您的代码!:)

Python为每个模块,类,函数或生成器表达式创建了一个新的范围(在Python 3.x中也用于列表推导).除此之外,函数内部没有嵌套的范围.

  • 编程中最重要的事情是管理应用程序的依赖关系和管理代码块范围的能力.匿名块允许您限制回调的生命周期,否则,您的回调只使用一次,但在程序的持续时间内存在,这会导致全局范围混乱并损害代码的可读性. (17认同)
  • "编程中最重要的是赋予某个名称的能力.第二个最重要的是不要求给出一些名字." 在大多数情况下,Python要求为范围(对于变量等)赋予名称.在这方面,Python变量是第二重要的测试. (10认同)
  • 我会重新措辞最后一句,因为您可以很好地在函数中创建函数。所以函数内部存在嵌套作用域。 (5认同)

小智 16

您可以通过在函数内声明函数然后立即调用它来在Python中执行类似于C++块作用域的操作.例如:

def my_func():
    shared_variable = calculate_thing()

    def do_first_thing():
        ... = shared_variable
    do_first_thing()

    def do_second_thing():
        foo(shared_variable)
        ...
    do_second_thing()
Run Code Online (Sandbox Code Playgroud)

如果你不确定为什么要这样做,那么这个视频可能会说服你.

基本原则是尽可能地将所有内容尽可能紧密地定义,而不将任何"垃圾"(额外的类型/功能)引入比绝对需要的范围更广的范围 - 没有其他人想要使用该do_first_thing()方法,因此它不应该在调用功能.


Har*_*nam 12

我同意没有块范围.但是在python 3中的一个位置使SEEM好像它有块范围.

发生什么事给了这个样子?这在python 2中正常工作.但是为了在python 3中使变量泄漏停止它们已经完成了这个技巧并且这个改变使它看起来好像它在这里有块范围.

让我解释.


根据范围的概念,当我们在同一范围内引入具有相同名称的变量时,应修改其值.

这就是python 2中发生的事情

>>> x = 'OLD'
>>> sample = [x for x in 'NEW']
>>> x
'W'
Run Code Online (Sandbox Code Playgroud)

但是在python 3中,即使引入了具有相同名称的变量,它也不会覆盖,但由于某种原因,列表理解就像沙箱一样,似乎在其中创建了一个新的范围.

>>> x = 'OLD'
>>> sample = [x for x in 'NEW']
>>> x
'OLD'
Run Code Online (Sandbox Code Playgroud)

这个答案违背了回答者@Thomas的陈述创建范围的唯一方法是函数,类或模块,因为这看起来像创建新范围的另一个地方.


小智 10

我提出了一个解决方案,该解决方案具有最简单的界面和最少的额外名称,可以引入到您的代码中。

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)
Run Code Online (Sandbox Code Playgroud)

https://pypi.org/project/scoping/