名称空间与作用域

名称空间与作用域

名称空间

名称空间(name spaces):

name = 'zkim' 就是在内存中开辟了一个新的空间,用来存放zkim,而namezkim具有绑定关系,我们能通过name找到zkim。那么name又存放在哪呢?...其实在内存中有一块内存存储变量名与变量间绑定关系的空间,而这个空间称之为名称空间。

  • 内置名称空间

内置名称空间:存放Python解释器自带的名字,如 print,len,int 等等。

生命周期:在Python解释器启动的时候生效,在解释器关闭的时候失效。

  • 全局名称空间

全局名称空间:除了内置和局部的名字之外,其余都存放在全局名称空间。如 x,func,l,z

x = 1          # x 存放于全局名称空间
print(x)

l = [1, 2] 	   # l 存放于全局名称空间
print(l)

if 3 > 2:
    if 4 > 3:
        z = 3  # z 存放于全局名称空间
print(z)

def func():    # func 存放于全局名称空间
    pass
print(func)
# 1
# [1, 2]
# 3
# <function func at 0x0000006D2E301EA0>

生命周期:在文件执行时生效,在文件执行结束后失效。

  • 局部名称空间

局部名称空间:用于函数调用期间,存放函数体产生的名字。如f2

def f1():
    def f2():  # f2 在f1的局部名称空间中
        print('from f2')
	f2()
    
f1()
# from f2

生命周期:在文件执行时函数调用期间生效,在函数执行结束后失效。

名称空间的加载顺序

1:python解释器先启动,因而首先加载的是:内置名称空间。

2:执行test.py文件,然后以文件为基础,加载全局名称空间。

3:在执行文件的过程中如果调用函数,则临时产生局部名称空间。

名字的查找顺序

  • 查找顺序只能是依次往上找:

内置名称空间--->全局名称空间--->内置名称空间

  • 从当前所在的位置开始查找:

当前在局部名称空间时:局部--->全局--->内置

当前在全局名称空间时:全局--->内置

# len = 1  全局名称空间   没有依次往上查找
def f1():
    # len = 2  f1的局部名称空间   没有依次往上查找
    def f2():
        # len =3  f2的局部名称空间   没有依次往上查找
        print(len)  # 从f2的局部名称空间开始查找 len 的值
    f2()
f1()
print(len)  # 当全局中找不到的时候回去内置中查找
# 内置中查找的结果:<built-in function len>

作用域

  • 域指的就是区域,作用域即作用的区域。

  • 全局作用域

全局有效,全局存活,包含内置名称空间和全局名称空间。

x = 1
def func():
    print(x)

func()
1
  • 局部作用域

局部作用域:局部有小,临时存储,只包含局部名称空间。

x = 1
def func():
    print(x)
    
def func2():
    x = 2
	func()

func2()
1

函数对象+作用域应用

def f1():
    def inner():
        print('from inner')
    return inner  # 将函数名 inner 当作返回值

f = f1()  # f = inner

def bar():
    f()  # inner()

bar()
# from inner

global 与 nonlocal 关键字

  • global 与 nonlocal 能够修改多个变量,如:
# global x,y,z  依次以逗号隔开
# nonlocal x,y,z  依次以逗号隔开
  • global 关键字
# 修改类型为不可变数据类型
name = 'jason'  # 全局变量

def f1():
    name = 'nick'
    
	def f2():
        global name  # 修改全局变量的值
        name = 'egon'
	f2()
f1()
print(name)
# egon
  • nonlocal 关键字
name = 'jason'

def f1():
    name = 'nick'  # 局部变量
    
	def f2():
        nonlocal name  # 修改局部变量的值
        name = 'egon'
	f2()
    print(name)
f1()
# egon
  • 注意点

1:在局部想要修改全局的可变类型,不需要任何声明,可以直接修改。

2:在局部如果想要修改全局的不可变类型,需要借助 global 声明,声明为全局的变量,即可直接修改。

lis = []
def func():
    lis.append(['jsaon','tank','nick','egon'])  # 一个列表整体代表一个元素
func()
print(lis)
[['jsaon', 'tank', 'nick', 'egon']]
千里之行,始于足下。
原文地址:https://www.cnblogs.com/jincoco/p/11165226.html