【问题标题】:Python binding environment on locals [duplicate]本地人的Python绑定环境[重复]
【发布时间】:2021-06-21 14:34:03
【问题描述】:

如下:

a = 3
def b():
    # global a; // will error without this statement
    a = a + 1
    print a

除非我添加global,否则它会出错。从这个意义上说,python 似乎首先评估表达式的 LHS(为a 创建一个新的本地)而不是先评估 RHS(等于 4)然后将其分配给本地 a。换句话说,比如:

local a <-- local a + 1
             ^
            doesnt exist so look up in parent environment
local a <-- global a + 1
local a <--    3     + 1

我只是好奇为什么在 python 中没有默认使用这种方法。例如,在 C 中它使用这种模式:

// file.c
#include <stdio.h>

int a=3;
int main(void)
{
    a = a + 1;
    printf("%d\n", a);
}
$ gcc file.c -o file; ./file
4

【问题讨论】:

  • " 从这个意义上说,python 似乎首先评估表达式的 LHS(为 a 创建一个新的本地)而不是 RHS 首先(等于 4)“不,发生的是 compilera 标记为本地,因此当您在表达式a += 1 中引用a 时,它会引发错误,因为未定义该本地变量。默认分配给全局变量会很糟糕。 Python 没有像 C 那样的变量声明,因此它使用一个简单的规则来解决这种歧义。注意,行为相反的语言是 JS,默认全局被认为是一个巨大的问题。
  • 注意,在 Python 中有一种情况,您可以执行类似 a = a + 1 的操作,其中 a 分配给本地范围并使用全局范围中的 a(如果存在),并且那是在类定义中,所以在里面,说一个class Foo: ...,如果你这样做a = a + 1,它将分配给类主体的本地a,但它将使用global a作为a + 1(没有其他a 已在类块中分配)

标签: python python-internals


【解决方案1】:

官方没有解释,但我能想到两个原因

  • 由于a = a + 1 是一个赋值,它指的是局部变量 a,而不是全局变量(除非另有说明)。由于您没有声明本地 a,因此它是隐式定义的,但未初始化(类似的事情也发生在 javascript 中,也是常见的混淆来源)。在 C 中您不会有这种误解,它是一种静态语言,如果存在,您将定义一个本地 int a
  • 在 python 中,您可以在函数b() 中定义一个函数c(),它将绑定到b 中的a 变量,而不是全局a。 C 没有闭包,所以这没什么用。

【讨论】:

  • C 是一种静态语言,这是一个很好的观点。我认为这可能就是为什么a=a+1 在 python 中可能会模棱两可。
  • @carl.hiass: 可能,因为它必须在全局读取(在右侧)和在本地写入(在左侧)。由于同名不能绑定两个不同的变量,确实有歧义。
  • "既然你还没有声明一个本地的a"... Python没有变量声明.
  • 是的,动态语言通常不使用 C 意义上的声明,但名称绑定仍然发生在第一次赋值时。这里没有发生这种情况,第一次赋值既读取又写入变量,因此有歧义
猜你喜欢
  • 2013-11-25
  • 2021-01-31
  • 2019-01-04
  • 1970-01-01
  • 1970-01-01
  • 2020-11-18
  • 1970-01-01
  • 2017-08-15
  • 2022-11-19
相关资源
最近更新 更多