【Python笔记】Python基础 —— 作用域

。_饼干妹妹 提交于 2019-11-30 06:16:09

作用域

.

  • 描述

作用域是针对变量而出现。当变量被赋值的时候,变量当前的位置就决定了变量能够被访问到的范围,这个范围就叫变量的作用域

官方文档:

A scope is a textual region of a Python program where a namespace is directly accessible. “Directly accessible” here means that an unqualified reference to a name attempts to find the name in the namespace.

.

  • 四种作用域(LEGB)

a.L(Local):最内层,包含局部变量,比如一个函数/方法内部

b.E(Enclosing):包含了非局部也非全局的变量

c.G(Global):当前脚本的最外层,比如当前模块的全局变量

d.B(Built-in):包含了内建的变量/关键字等

.

  • 作用域的规则

a.本地作用域是函数内部属于本函数的作用范围,因为函数可以嵌套函数,嵌套的内层函数有自身的内层范围

b.嵌套函数的本地作用域是属于内层函数的范围,不属于外层

c.全局作用域是文件级别的,或者说是模块级别的,每个py文件中处于顶层的变量都是全局作用域范围内的变量

d.内置作用域是预先定义好的,在__builtins__模块中。这些名称主要是一些关键字,例open、range、list等
.

  • 实例

x = 1

def out1(i):
    x = 2
    y = 'a'
    print(x)
    print(i)
    
    def in1(n):
        print(n)
        print(x,y)
    in1(3)

out1(2)

输出结果:

2
2
3
2 a

a.处于全局作用域范围的变量有:x、out1

b.处于out1本地作用域范围的变量有:i、x、y、in1

c.处于嵌套在函数out1内部的函数in1的本地作用域范围的变量有:n

:函数名out1和in1也是一种变量
.

  • 搜索规则

当在某个范围引用某个变量的时候,将从它所在的层次开始搜索变量是否存在,不存在则向外层继续搜索

例如函数f()中嵌套了一个函数g(),g()中有一个语句print(x),它将首先检查g()函数的本地作用域内是否有x,如果没有则继续检查外部函数f()的本地作用域范围内是否有x,如果没有则再次向外搜索全局范围内的变量x,如果还是没有,则继续搜索内置作用域像‘x’这种变量名,在内置作用域范围内是不存在的,所以最终没有搜索到,报错

.

  • 全局变量

a.每个py文件(模块)都有一个自己的全局范围

b.文件内部顶层的,不在def区块内部的变量,都是全局变量

c.def内部声明(赋值)的变量默认是本地变量,要想让其变成全局变量,需要使用global关键字声明

d.def内部如果没有申明(赋值)某变量,则引用的这个变量是全局变量


x = 2 

def f():
    x = 3
    print(x)

f()         #输出结果:3

print(x)    #输出结果:2

使用global关键字


x = 2

def f():
    global x
    x = 3
    print(x)

f()        #输出结果:3

print(x)   #输出结果:3

.

  • 变量掩盖和修改规则

a.如果在函数内部引用了一个和全局变量同名的变量,且不是重新定义、重新赋值,那么函数内部引用的是全局变量


x = 3
def g():
    print(x)    #引用了全局变量

#输出结果:3

b.如果函数内部重新赋值了一个和全局变量名称相同的变量,则这个变量是本地变量,他会掩盖全局变量

注:掩盖而非覆盖,出了函数的范围(函数退出),全局变量就会恢复


x = 3

def g():
    x = 2       #定义并赋值本地变量x
    print(x)    #引用本地变量x

#输出结果:2
     

c.在函数内修改和全局变量同名的变量前,必须先修改,在使用该变量


x = 1

def g():
    print(x)
    x = 2
    
g()

输出结果:UnboundLocalError: local variable 'x' referenced before assignment

python是逐行解释的,但每个函数属于一个区块,这个区块范围是一次性解释的,读完整个区块再解释。所以读完整个g()区块后,首先就记住了重新定义了本地变量x=2,于是g()中所有使用变量x的时候,都是本地变量x,所以print(x)中的x也是本地变量,但这违反了使用变量前先赋值的规则,所以会报错

.

  • 代码块

代码块可以使得一段python代码作为一个单元、一个整体执行

类型:

a.模块文件是一个代码块

b.函数体是一个代码块

c.class的定义是一个代码块

d.交互式(python idle)的每一个命令行都是一个独立的代码块

e.脚本文件是一个代码块

f.脚本命令是一个代码块

g.eval()和exec()中的内容也都是各自的代码块
.

  • 课堂拓展

a.全局变量的不安全性

b.访问其他模块中的全局变量

c.其他访问全局变量的方法

d.nonlocal关键字

e.访问外层函数变量的其他方法

点击学习

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!