首页 > 编程知识 正文

全局变量的作用域是,未解析的引用

时间:2023-05-06 05:14:49 阅读:19545 作者:2485

本文介绍了Python变量作用域代码的分析。 文章代码介绍得很详细。 我觉得编辑很好。 因为现在只是作为参考进行共享,所以有必要的伙伴看看吧。

特长

python的范围是静态的,源代码中变量名称被赋值的位置决定了该变量可以访问的范围。 也就是说,Python变量的范围由变量在源代码中的位置决定。 Python不会在所有语句块中生成范围。 只有在Module (模块)、Class (类)、def (函数)中定义了变量时,才存在范围概念。

1 .函数内部的变量无法从函数外部访问

deffunc(:

可变=100

是打印(可变)

print (可变) # name 'variable' is not defined

2 .函数上层的变量(标量)是只读的,不能重新定义。 初始化

defcounter1(:

n=0

def计算(:

n=n 1 # n是一个标量(数字、字符串、浮点数),Python程序表示:“如果内部函数具有引用外部函数的同名变量或全局变量,并且Python将该变量识别为局部变量,并且函数具有n

# y=n 1 #变更为y就可以了

#返回y

返回n

返回计算

可变=300

def test_scopt () :

print(variable ) #此时调用局部变量variable,且未绑定到内存对象(未定义、未初始化或未赋值)。 本质上遵循LEGB定律

variable=200 #其中,variable是局部变量,因为之前调用过一次

写在#print(variable ) )以下就可以了。 因为variable是新的局部变量,而不是重定义,却没有绑定

test_scopt ()

Python的模块代码在运行前不会进行预编译,但模块中的函数主体代码在运行前进行预编译,因此,无论变量名称绑定发生在作用域中的哪个位置,编译器都会知道。 虽然Python是静态范围语言,但变量名称查找是动态发生的,并且在程序运行之前不会发现范围问题

3. list、dict等复合变量中的值均可参考变更

def counter () :

n=[0]

def计算(:

n[0] =1 #是更改n中的第一个值,而不是更改n

return n[0]

返回计算

func=counter ()

func(#1

func(#2

func(#3

4 .如果4. global声明全局变量并在局部修改全局变量,则必须首先在局部声明全局变量

defcounter1(:

n=0

def计算(:

global n #如果要在局部修改全局变量,则必须在局部声明全局变量,但由于没有全局变量n,因此这里也会报告错误

n =1

返回n

返回计算

# right

defcounter1(:

全球n

n=0

def计算(:

全球n

n =1

返回n

返回计算

5. nonlocal关键字用于在函数或其他作用域中使用外部(非全局)变量

def make_counter () :

计数=0

def counter () :

非局部计数#使用外部非全局变量

计数=1

返回计数

返回计数器

范围类型

在Python中,使用变量时不需要预声明,但在实际使用变量之前,必须绑定到内存对象(此变量名称绑定在当前范围中引入新变量,并使用外部范围中同名的变量

L(local )局部范围

局部变量:包含在由def关键字定义的语句块中,也就是由函数定义的变量中。 每次调用函数时都会创建新的本地范围。 Python也有递归。 自己调用自己,每次调用都创建新的本地名称空间。 缺省情况下,函数中的变量声明是局部变量,除非将其声明为全局变量。 如果需要在函数中定义全局变量,可以使用global关键字全局声明变量的范围。 局部变量域就像一个

p>栈,仅仅是暂时的存在,依赖创建该局部作用域的函数是否处于活动的状态。所以,一般建议尽量少定义全局变量,因为全局变量在模块文件运行的过程中会一直存在,占用内存空间。

注意:如果需要在函数内部对全局变量赋值,需要在函数内部通过global语句声明该变量为全局变量。

E(enclosing)嵌套作用域

E也包含在def关键字中,E和L是相对的,E相对于更上层的函数而言也是L。与L的区别在于,对一个函数而言,L是定义在此函数内部的局部作用域,而E是定义在此函数的上一层父级函数的局部作用域。主要是为了实现Python的闭包,而增加的实现。

G(global)全局作用域

即在模块层次中定义的变量,每一个模块都是一个全局作用域。也就是说,在模块文件顶层声明的变量具有全局作用域,从外部开来,模块的全局变量就是一个模块对象的属性。

注意:全局作用域的作用范围仅限于单个模块文件内

B(built-in)内置作用域

系统内固定模块里定义的变量,如预定义在builtin 模块内的变量。

作用域链:变量名解析LEGB法则

搜索变量名的优先级:局部作用域 > 嵌套作用域 > 全局作用域 > 内置作用域

LEGB法则: 当在函数中使用未确定的变量名时,Python会按照优先级依次搜索4个作用域,以此来确定该变量名的意义。首先搜索局部作用域(L),之后是上一层嵌套结构中def或lambda函数的嵌套作用域(E),之后是全局作用域(G),最后是内置作用域(B)。按这个查找原则,在第一处找到的地方停止。如果没有找到,则会出发NameError错误。

example 1

name = "lzl"

def f1():

print(name)

def f2():

name = "eric"

f1()

f2() # 在函数未执行之前,作用域链就已经形成了,此时f1()的上一级应该name = 'lzl'

example 2

def scope_test():

def do_local():

spam = "local spam" # 此函数定义了另外的一个spam字符串变量,并且生命周期只在此函数内。此处的spam和外层的spam是两个变量,如果写出spam = spam + “local spam” 会报错

def do_nonlocal():

nonlocal spam # 使用外层的spam变量 test spam

spam = "nonlocal spam"

def do_global():

global spam

spam = "global spam"

spam = "test spam"

do_local()

print("After local assignmanent:", spam) # test spam

do_nonlocal()

print("After nonlocal assignment:",spam) # nonlocal spam

do_global()

print("After global assignment:",spam) # nonlocal spam ???? 先找是本地变量,找到的本地变量已经在do_nonlocal()里面改变了所以输出的是nonlocal spam

scope_test()

print("In global scope:",spam) # global spam

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。