Python入门(三十)命名空间和作用域

您所在的位置:网站首页 python命名空间顺序 Python入门(三十)命名空间和作用域

Python入门(三十)命名空间和作用域

2024-07-07 17:29| 来源: 网络整理| 查看: 265

函数(包括方法)是Python代码的主要组织形式,那你有没有发现,在函数中实际是可以引用函数外的变量的,但是在函数外面不能引用函数里的变量。

a = 10 def foo(): b = a ** 2 #函数内部可以引用外部的变量 print(f"{a=}, {b=}") foo() #a=10, b=100 print(b) #NameError: name 'b' is not defined 但是外部不能使用函数内的变量

这种限制我们称呼变量的作用域限制。

每个变量只有一定范围内有效,这个范围我们称之为作用域。

上面的例子中,变量a是全局变量,它的作用域是全局的,程序中的任意地方都可以访问它,但是在函数内部定义的变量b,它是局部变量,它的作用域是函数内部,只在函数内部可以访问它。

所谓作用域就是指变量名/对象名在多大范围内是可见的/有效的,一个变量名既不能作用域太大,这样会引发广泛的命名冲突,也不能太小,这样很难实现变量的共享,所以一般都有多层次的作用域。一个层次的作用域,在Python里称为命名空间。

命名空间

Python的命名空间有三个层次(作用域):

内置名称(built-in names), Python 语言内置的名称,比如函数名 abs、char 和异常名称 BaseException、Exception 等等,他们可以在任何地方进行直接的访问,不需要import。全局名称(global names),模块中定义的名称,记录了模块的变量,包括函数、类、其它导入的模块、模块级的变量和常量,如果要扩模块访问,需要import导入,遵循模块使用的规则。局部名称(local names),函数中定义的名称,记录了函数的变量,包括函数的参数和局部定义的变量。(类中定义的也是)

在使用变量的过程中,命名空间的查找顺序是:

局部的命名空间 -> 全局命名空间 -> 内置命名空间。

也就是说,如果我们发现一个变量,首先看它是不是一个局部变量(在函数内部有被赋值),如果不是局部变量,看是否是一个全局变量(在函数外是否有被赋值),如果不是全局变量,可能是Python内置的变量,如果也不是内置变量,那这个变量就是未定义的。

反向来看,如果出现了重名,全局变量的名字将覆盖Python的内置变量,局部变量将覆盖全局变量。

比如下面的例子:

a = 10 def foo(): a = 20 print(f"在函数foo()内 {a=}") foo() print(f"在函数foo()执行后 {a=}")

首先定义了全局变量a,在函数里给a进行了赋值,在调用函数后,打印a的值,仍然是在全局变量时赋的值,全局变量的值并没有变化。

在函数外的

a = 10

实际是定义了一个为10的变量a

同样,在函数里

a = 20

是定义了一个为20 的变量a,这里的a是局部变量,而前面那个a是全局变量,当我们在函数里访问a时,访问的是定义的局部变量a。

那有没可能我在定义局部变量之前先访问全局变量呢?

def foo(): print(f"在函数foo()内,刚开始访问", a) a = 20 print(f"在函数foo()内 {a=}") foo() print(f"在函数foo()执行后 {a=}") #UnboundLocalError: cannot access local variable 'a' where it is not associated with a value

实际上是不行,解释器分析发现这两个地方有冲突,直接给出了UnboundLocalError的异常。

作用域

作用域就是一个 Python 程序可以直接访问命名空间的变量、函数区域。

命名空间是从变量的角度来看的,就是这个变量在那个空间能被看到,作用域是从程序访问的角度来看的,就是在这个层级函数或方法可以访问到哪些变量。

作用域分层四个域:

L(Local):最内层,包含局部变量,比如一个函数/方法内部。E(Enclosing):闭包,这个后面会学习。G(Global):当前程序的最外层,比如当前模块的全局变量。B(Built-in): 包含了内建的变量/关键字等,最后被搜索。

作用域的搜索层级是L –> E –> G –> B。

在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再者去内置中找。

g_count = 0 # 全局作用域 def foo(): l_count = 1 # 局部作用局

内置作用域是通过一个名为 builtin 的标准模块来实现的,但是这个变量名自身并没有放入内置作用域内,所以必须导入这个文件才能够使用它。在Python3.0中,可以使用以下的代码来查看到底预定义了哪些变量:

import builtins print(dir(builtins))

几乎所有的内置函数、内置异常都在这里面。

Python 中只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域,其它的代码块(如 if/elif/else/、try/except、for/while等)是不会引入新的作用域的,也就是说这些语句内定义的变量,外部也可以访问,如下代码:

if True: msg = '作用域变量' print(msg) #作用域变量

这与C++、Java语言等有很大的不同。

全局变量和局部变量

定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域。

局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。调用函数时,所有在函数内声明的变量名称都将被加入到作用域中。如下实例:

total = 0 # 这是一个全局变量 # 可写函数说明 def sum( arg1, arg2 ): #返回2个参数的和." total = arg1 + arg2 # total在这里是局部变量. print ("函数内是局部变量 : ", total) return total #调用sum函数 sum( 10, 20 ) print ("函数外是全局变量 : ", total) #函数内是局部变量 : 30 #函数外是全局变量 : 0 global 关键字

当内部作用域想修改外部作用域的变量时,就要用到 global 关键字了。

global声明变量是全局变量,例如:

num = 1 def fun1(): global num # 需要使用 global 关键字声明 print(num) num = 123 print(num) fun1() print(num) ’’’ 1 123 123 ‘’‘

以上就是“Python入门(三十)命名空间和作用域”的全部内容,希望对你有所帮助。 ​ ​关于Python技术储备

学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!

一、Python所有方向的学习路线

Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

在这里插入图片描述

二、Python必备开发工具

img

三、Python视频合集

观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。

img

四、实战案例

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

img

五、Python练习题

检查学习结果。

img

六、面试资料

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

img

最后祝大家天天进步!!

上面这份完整版的Python全套学习资料已经上传至CSDN官方,朋友如果需要可以直接微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3