Python Notes

全局作用域与局部作用域的关系

Python中只有模块、类以及函数才会引入新的作用域。
在其他语言中:

#include<stdio.h>
int main() {
    if(2 > 0) {
        int i = 0;
    }
    printf("i = %d", i);
    return 0;
}

上述代码中,if子句引入了一个局部作用域,printf函数中对变量i的引用会引发编译错误。

在Python中:

if True:
    i = 0
print i

if子句并没有引入一个局部作用域,变量i仍然处在全局作用域中,因此,变量i对于接下来的print语句是可见的。

模块是一个全局作用域

每一个模块是一个全局作用域——一个名字空间,变量名在一个模块文件顶层生成(赋值)。

对函数的每个调用是一个新的局部作用域

每次你调用一个函数,生成一个新的局部作用域——是在函数的内部生成的名字所在的一个名字空间。

赋值的名字是局部的,除非声明是全局

默认情况下,在函数中赋值的名字都放到局部作用域中(函数调用相关的名字空间)。如果你需要赋值一个名字,而该名字又在包括在函数的模块顶层的话,你可以通过在一个函数中用一个global语句声明是全局的。(由于该名字已经存在于包括该函数的模块顶层(即全局变量),若想在函数中对其进行赋值,默认情况下放弃了全局变量,在局部作用域中又产生了一个局部变量,若想保留该变量的全局性,可以通过在函数中用一个global语句声明是全局的)

i = 0
def f():
    i = 8
    print i
f()
print i

运行结果:8和0。i = 8是一个名字绑定操作,它在函数f的局部作用域中引入了新的变量i,屏蔽了全局变量i,因此f内部的print语句看到的是局部变量i,f外部的print语句看到的是全局变量i。

i = 0
def f():
    print i
    i = 0
f()

运行结果显示:UnboundLocalError: local variable ‘i’ referenced before assignment。在这个例子当中,函数f中的变量i是局部变量,但是在print语句使用它的时候,它还未被绑定到任何对象之上,所以抛出异常。

所有其他的名字都是全局的或内置的

函数定义中没赋值的名字均被认为是全局的(在包含它的模块的名字空间中)或内置的(在Python提供的预定义名字空间中)。

参数传递

参数通过局部名字传递

函数参数时候对共享对象的引用,被调用者所引用。

在一个函数中对参数名赋值不影响调用者

函数首部中的参数名当函数运行时在作用域中成为新的局部名字。函数的参数名字不是调用者使用的名字的别称。

在一个函数中改变一个可变的对象参数可能影响调用者

在另一方面,既然参数只是简单的赋值给对象,函数能改变被传递的可变对象,结果可能影响调用者。见下面例子:

>>>def changer(x,y)
       x = 2
       y[0] = 'spam'
>>>X = 1
>>>L = [1,2]
>>>changer(X,L)
>>>X,L
(1,[''spam,2])
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值