最新消息:

python变量的作用域问题

未分类 admin 3417浏览 0评论

在 Python 程序中创建、改变或查找变量名时,都是在一个保存变量名的地方进行中,那个地方我们称之为命名空间。作用域这个术语也称之为命名空间。

具体地说,在代码中变量名被赋值(Python 中变量声明即赋值,global 声明的只是变量的使用域)的位置决定了该变量能被访问的范围。函数定义了本地作用域,而模块定义的是全局作用域。这两个作用域之前有如下关系:

每一个模块都是全局作用域。也就是说,创建于模块文件顶层的变量具有全局作用域,对于外部访问就成了一个模块 对象的属性。

 

全局作用域的作用范围仅限于单个文件。“全局”指的是在一个文件的顶层变量名对于这个文件而言是全局的。每次对函数的调用都创建了一个新的本地作用域。Python 中也有递归,即可以调用自身,每次调用都会创建五个新的本地命名空间。赋值的变量名除非声明为全局变量,否则均为本地变量。如果需要在函数内部对模块文件顶层的变量名赋值,需要在 函数内部通过 global 语句声明该变量。所有的变量可归纳为本地、全局或者内置三种。范围分别为 def 内部,在一个模块的命名空间内部和预定义的 __builtin__ 模块提供的变量。变量名解析:LEGB 原则

如果对以上内容有所迷惑的话,请看以下总结出的几条原则。在函数命名空间中:

变量名引用分为三个作用域进行查找:首先是本地,然后是函数内(如果有的话),之后是全局,最后是内置。在默认情况下,变量名赋值会创建或者改变本地变量。全局声明将会给映射到模块文件内部的作用域的变量名赋值。Python 的变量名解析机制也称为 LEGB 法则,具体如下:
当在函数中使用未确定的变量名时,Python 搜索 4 个作用域:本地作用域(L),之后是上一层嵌套结构中 def 或 lambda 的本地作用域(E),之后是全局作用域(G),最后是内置作用域(B)。按这个查找原则,在第一处找到的地方停止。如果没有找到,Python 会报错的。 下图说明了搜索流程(由内及外):

作用域实例

# -*- coding: utf8 -*-# 全局作用域
x = 99  # x 和 func 函数在模块中声明,为全局使用域

def func(y):
# 本地作用域
z = x + y  # x 为全局变量
return z

func(1)  # func 在模块中定义,可以调用.结果=100

以上信息来至:http://magicalboy.com/python-scope-legb.html

另注意比对PHP代码,python代码:

 

<?php

$s = 3;

function  s(){

global $s;

$s = 2;

}

s();

echo $s;//注意输出为 2

 

 

test.py

 

 

x = 88

y = 2

def func():

global y

#虽然在y在函数内部重新定义前是全局的,

#但是如果函数内有相同的变量那这两个y将是完全不同的变量 了

#所以只能通过global关键字来改变y的值

 

 

x = 99

y = 55

func()

print(‘X is %d , Y is %d’%(x,y)) #输出:X is 88 , Y is 55

 

 

这里在函数调用前x,y都是全局变量。但当在函数内部遇到同名变量时,已被划分为本地变量。

特别:在函数内部定义的任意的赋值操作变量名都为本地变量:=语句,import,def(注意def 也是赋值操作,上例中将一个函数对象赋值给了func变量),参数传递。

但需要注意本地改变对象时并不会把变量划分为本地变量。如: L.append(x) 并不会让L为本地变量,而L= x 却可以。

转载请注明:爱开源 » python变量的作用域问题

您必须 登录 才能发表评论!