基于局部变量的Python绑定环境

基于局部变量的Python绑定环境,python,python-internals,Python,Python Internals,在以下方面: 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 ^

在以下方面:

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

没有官方的解释,但我可以想到两个原因


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

这是C语言作为静态语言的一个重要观点。我认为这可能就是为什么在python中
a=a+1
可能不明确的原因。@carl.hiass:可能是因为它必须全局读取(在右侧)和本地写入(在左侧)。由于同一个名称不能绑定到两个不同的变量,因此确实存在歧义。。。Python没有变量声明。是的,动态语言通常不使用C意义上的声明,但是名称绑定仍然发生在第一次赋值时。这里没有发生这种情况,第一个赋值同时读取和写入变量,因此存在歧义“从这个意义上讲,python首先计算表达式的LHS(为a创建一个新的局部),而不是RHS第一个(等于4)”“不,发生的是编译器将
a
标记为局部,因此,当您在表达式
a+=1
中引用
a
时,将引发错误,因为未定义该局部变量。默认为全局变量赋值是不好的。Python没有像C这样的变量声明,所以它使用一个简单的规则来解决这种歧义。注意,行为相反的语言是JS,默认全局被认为是一个巨大的问题。注意,在Python中有一种情况,您可以执行类似于
a=a+1
的操作,其中
a
分配给局部作用域,并从全局作用域(如果存在)使用
a
,这是在类定义中,所以在内部,说一个
类Foo:…
如果你这样做
a=a+1
它将分配给类主体的
a
本地,但它将使用
全局a
来分配
a+1
(在类块中没有分配任何其他
a
// 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