Python3之命名空间和作用域

一、命名空间

命名空间(Namespace)是从名称到对象的映射,大部分的命名空间都是通过 Python 字典来实现的;

命名空间提供了项目中避免名字冲突的一种方法,各个命名空间是独立没有任何关系的,因此一个命名空间中不能有重名,但不同的命名空间是可以重名而没有任何影响;如Windows系统一个目录下文件名不能重名,但不能目录下文件可重名

Python中一般有三种命名空间:

  • 内置名称(bulit-in names):Python语言的内置名称,如函数名 abs、char 和异常名称 BaseException、Exception 等
  • 全局名称(global names):模块中定义的名称,记录了模块的变量,包括函数、类、其它导入的模块、模块级的变量和常量等
  • 局部名称(local names):函数或类中定义的名称,记录了函数的变量,包括函数的参数和局部定义的变量等

命名空间的范围大小:内置名称>全局名称>局部名称

命名空间的查找顺序:局部命名空间 -> 全局命名空间 -> 内置命名空间,如果均找不到,报错NameError 异常:

NameError: name 'xxx' is not defined

命名空间的生命周期:命名空间的生命周期取决于对象的作用域,如果对象执行完成,则该命名空间的生命周期就结束。因此,我们无法从外部命名空间访问内部命名空间的对象

二、作用域

作用域就是一个 Python 程序可以直接访问命名空间的正文区域;

Python 程序中,访问一个变量会从内到外依次访问所有的作用域直到找到,否则会报未定义的错误;

Python的作用域一共有4种,分别为:

  • L(Local):最内层,包含局部变量,比如一个函数/方法内部
  • E(Enclosing):包含了非局部(non-local)也非全局(non-global)的变量。比如两个嵌套函数,一个函数(或类) A 里面又包含了一个函数 B ,那么对于 B 中的名称来说 A 中的作用域就为 nonlocal;
  • G(Global):当前脚本的最外层,比如当前模块的全局变量;
  • B(Built-in): 包含了内建的变量/关键字等,最后被搜索

规则顺序: L –> E –> G –> B

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

import builtins
dir(builtins)

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

三、全局变量和局部变量

全局变量:定义在函数外的变量,全局变量可以在整个程序范围内访问;

局部变量:定义在函数内的变量,局部变量只能在其被声明的函数内部访问;

调用函数时,所有在函数内声明的变量名称都将被加入到作用域中;

# 1、全局变量和局部变量
# 定义全局变量
globalvalue = 0

def sum(arg1, arg2):
    #globalvalue在函数里是局部变量
    globalvalue = arg1 + arg2
    print("函数内是局部变量 : " , globalvalue)
    return globalvalue

# 调用sum函数
sum(10, 20)
print("函数外是全局变量 : ", globalvalue)
函数内是局部变量 :  30
函数外是全局变量 :  0

四、global 和 nonlocal关键字

global 和 nonlocal关键字主要用于内部作用域需要修改外部作用域的变量;global 关键字主要用于局部变量修改全局变量;nonlocal关键字主要用于修改嵌套作用域(enclosing 作用域,外层非全局作用域)中的变量

# global 关键字主要用于局部变量修改全局变量
# 全局变量num
num = 1
def fun1():
    global num  #需要使用 global 关键字声明
    print("输出修改前全局变量值:" , num)  #输出修改前全局变量值
    num = 123   #局部作用域修改全局变量的值
    print("输出修改后全局变量值:" , num)  #输出修改后全局变量值
# 函数调用
fun1()
# 全局变量值已被修改
print("全局变量值已被修改:" , num)

# global 关键字主要用于局部变量修改全局变量
def outer():
    num = 10 # 局部变量,enclosing 作用域
    # 函数嵌套
    def inner():
        nonlocal num # nonlocal关键字声明
        num = 100 # 修改enclosing 作用域的值
        print("inner函数输出修改后的值:" , num) # 输出修改后的值
    inner()
    print("num已被修改:" , num)
outer()
输出修改前全局变量值: 1
输出修改后全局变量值: 123
全局变量值已被修改: 123
inner函数输出修改后的值: 100
num已被修改: 100

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值