函数python的作用域 python函数作用的描述

Python语言中作用域怎么理解?命名空间 是从命名到对象的映射 。当前命名空间主要是通过 Python 字典实现的,不过通常不关心具体的实现方式(除非出于性能考虑) , 以后也有可能会改变其实现方式 。以下有一些命名空间的例子:内置命名(像 abs() 这样的函数,以及内置异常名)集,模块中的全局命名 , 函数调用中的局部命名 。某种意义上讲对象的属性集也是一个命名空间 。关于命名空间需要了解的一件很重要的事就是不同命名空间中的命名没有任何联系,例如两个不同的模块可能都会定义一个名为 maximize 的函数而不会发生混淆-用户必须以模块名为前缀来引用它们 。
顺便提一句,我称 Python 中任何一个“.”之后的命名为 属性 --例如 , 表达式 z.real 中的 real 是对象 z 的一个属性 。严格来讲,从模块中引用命名是引用属性:表达式 modname.funcname 中 , modname 是一个模块对象 , funcname 是它的一个属性 。因此,模块的属性和模块中的全局命名有直接的映射关系:它们共享同一命名空间![1]
属性可以是只读过或写的 。后一种情况下,可以对属性赋值 。你可以这样做: modname.the_answer = 42。可写的属性也可以用 del 语句删除 。例如: del modname.the_answer 会从 modname 对象中删除 the_answer 属性 。
不同的命名空间在不同的时刻创建,有不同的生存期 。包含内置命名的命名空间在 Python 解释器启动时创建,会一直保留,不被删除 。模块的全局命名空间在模块定义被读入时创建,通常,模块命名空间也会一直保存到解释器退出 。由解释器在最高层调用执行的语句,不管它是从脚本文件中读入还是来自交互式输入,都是 __main__ 模块的一部分,所以它们也拥有自己的命名空间(内置命名也同样被包含在一个模块中,它被称作 builtins ) 。
当调用函数时,就会为它创建一个局部命名空间,并且在函数返回或抛出一个并没有在函数内部处理的异常时被删除 。(实际上,用遗忘来形容到底发生了什么更为贴切 。)当然 , 每个递归调用都有自己的局部命名空间 。
作用域 就是一个 Python 程序可以直接访问命名空间的正文区域 。这里的直接访问意思是一个对名称的错误引用会尝试在命名空间内查找 。尽管作用域是静态定义,在使用时他们都是动态的 。每次执行时,至少有三个命名空间可以直接访问的作用域嵌套在一起:
python中函数变量作用域和类变量作用域怎么搞都错 , 烦躁中?python中 , 变量的作用域要弄清楚 。只有module、class、def、lambda才会引入作用域 , 其他的代码块是不会引入作用域的 。
1
图一中,你在函数中声明了d为全局变量,但这样是无效的,程序运行结果,已经说明这一点 。
global这个关键字,是用来“在函数中修改全局变量值”的声明,而不是“在局部函数中定义一个全局变量”的声明 。这里要注意一下 。
你可以再局部函数外面声明变量d,再加上你原先的函数,就可以修改、访问这个变量了 。
2
在类中函数的变量 , 作用域只在函数中 。图二中 , jian这个变量分别在yu() , yu1()两个函数中,是处于不同的定义域中的,是不能相互访问的 。
所以,在各自函数中,只有先定义了jian变量,才能再使用 。
如果想在yu1()中访问yu()中的jian变量,就需要将jian变量变成全局变量,即在class中定义一个全局变量jian,这样yu1(),yu()函数都可以访问了
python跨模块作用域python中函数python的作用域的作用域分4种情况:
L:local,局部作用域,即函数中定义的变量函数python的作用域;
E:enclosing,嵌套的父级函数的局部作用域,即包含此函数的上级函数的局部作用域,但不是全局的;
G:globa , 全局变量 , 就是模块级别定义的变量;
B:built-in,系统固定模块里面的变量 , 比如int, bytearray等 。搜索变量的优先级顺序依次是:作用域局部外层作用域当前模块中的全局python内置作用域,也就是LEGB 。
1
2
3
4
5
6
7
8
9
10
11
12
13
x = int(2.9)# int built-in
g_count = 0# global
def outer():
o_count = 1# enclosing
def inner():
i_count = 2# local
print(o_count)
【函数python的作用域 python函数作用的描述】# print(i_count) 找不到
inner()
outer()
# print(o_count) #找不到
当然,local和enclosing是相对的,enclosing变量相对上层来说也是local 。
5.2 作用域产生
在Python中,只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域,其它的代码块(如if、try、for等)是不会引入新的作用域的,如下代码:
1
2
3
if 21:
x = 1
print(x)# 1
这个是没有问题的,if并没有引入一个新的作用域,x仍处在当前作用域中,后面代码可以使用 。
1
2
3
def test():
x = 2
print(x) # NameError: name 'x2' is not defined
def、class、lambda是可以引入新作用域的 。
5.3 变量的修改
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#################
x=6
def f2():
print(x)
x=5
f2()
# 错误的原因在于print(x)时,解释器会在局部作用域找,会找到x=5(函数已经加载到内存),但x使用在声明前函数python的作用域了,所以报错:
# local variable 'x' referenced before assignment.如何证明找到了x=5呢?简单:注释掉x=5,x=6
# 报错为:name 'x' is not defined
#同理
x=6
def f2():
x =1 #local variable 'x' referenced before assignment.
f2()
5.4 global关键字
当内部作用域想修改外部作用域的变量时 , 就要用到global和nonlocal关键字了,当修改的变量是在全局作用域(global作用域)上的,就要使用global先声明一下,代码如下:
1
2
3
4
5
6
7
8
9
count = 10
def outer():
global count
print(count)
count = 100
print(count)
outer()
#10
#100
5.5 nonlocal关键字
global关键字声明的变量必须在全局作用域上,不能嵌套作用域上 , 当要修改嵌套作用域(enclosing作用域,外层非全局作用域)中的变量怎么办呢 , 这时就需要nonlocal关键字了
1
2
3
4
5
6
7
8
9
10
11
def outer():
count = 10
def inner():
nonlocal count
count = 20
print(count)
inner()
print(count)
outer()
#20
#20
5.6 小结
(1)变量查找顺序:LEGB,作用域局部外层作用域当前模块中的全局python内置作用域;
(2)只有模块、类、及函数才能引入新作用域;
(3)对于一个变量 , 内部作用域先声明就会覆盖外部变量,不声明直接使用,就会使用外部作用域的变量;
(4)内部作用域要修改外部作用域变量的值时,全局变量要使用global关键字,嵌套作用域变量要使用nonlocal关键字 。nonlocal是python3新增的关键字 , 有了这个 关键字,就能完美的实现闭包了 。
函数python的作用域的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于python函数作用的描述、函数python的作用域的信息别忘了在本站进行查找喔 。

    推荐阅读