python基础:函数命名空间、作用域、全局变量和局部变量

一、命名空间:
Python的命名空间的本质是一个字典,用来记录变量名称和值。字典的key是变量的名称,字典的value对于的是变量的值。
例如 {‘name’:’zs’,’age’:10}
命名空间一共分为三种:局部命名空间、全局命名空间、内置命名空间
局部命名空间:
每个函数都有自己的命名空间,叫做局部空间,它记录了函数的变量,包括函数的参数 和局部定义的变量
全局命名空间:
每个模块拥有它自已的命名空间,叫做全局命名空间,它记录了模块的变量,包括函数、 类、其它导入的模块。
内置命名空间:
任何模块均可访问它,它存放着内置的函数和异常。
input,print,str,list,tuple…

c=10

def func():
    a=10
    b=20
    #{'a':10,'b':20}


#func()   #内存地址(),函数名本质就是内存地址()来调用方法
func1=func   #把func内存地址赋值给func1

print(func)

在这里插入图片描述
# 局部变量:{‘a’:10,‘b’:20}
# 全局变量:{‘c’:10,‘func’:’<function func at 0x00000000004C2E18>(func对应的内存地址)’}

# 内置命名空间:纪录的是内置函数:例如:print(),id(),type()....
# {'print':'内存地址','id';'内存地址'}

1、访问命名空间的内容:

使用locals()内置函数来查看局部命名空间中的内容
使用globals()内置函数来查看全局命名空间的内容

注意:
如果locals()没有在函数体中,而是在py文件中,打印出来的内容和
glabals()相同。

d = 30
def func(c):
    a = 10
    b = 20
    print(locals())
    # {'b': 20, 'a': 10, 'c': 30}
func(30)
print(globals())
print(locals())

运行结果:

{'b': 20, 'a': 10, 'c': 30}
{'__name__': '__main__', '__doc__': '\n1、使用locals()内置函数来查看局部命名空间中的内容\n2、使用globals()内置函数来查看全局命名空间的内容\n\n注意:\n如果locals()没有在函数体中,而是在py文件中,打印出来的内容和\nglabals()相同。\n', '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000000000063D080>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'E:/homework/pythonworksplace/day08/demon02-访问命名空间中的内容.py', '__cached__': None, 'func': <function func at 0x00000000005C2E18>}

2、命名空间的加载顺序
内置命名空间(程序运行前加载)->全局命名空间(程序运行中:从上到下加载)->局部命名空间(程序运行中:调用时才加载)当函数返回结果 或 抛出异常时,被删除。每一个递归调用的函数都拥有自己的命名空间。
内置命名空间>全局命名空间>局部命名空间

a = 10
b = 20
def func():
    c = 20
    print(c)
func()
print(a)
print(b)

运行结果:

20
10
20

3、命名空间的查找顺序
当使用某个变量的时候,先从局部命名空间中找,如果能找到则停止搜索,如果找不到在去全局名称空间中查找,如果找到则停止搜索,如果找不到则到内置名称空间中查找,如果找不到则报错。
(1)命名空间的顺序:
局部命名空间 全局命名空间 内置命名空间
先从局部命名空间这种查找,如果能查找到,则停止搜索,
如果找不到就去全局命名空间中查找,如果找到停止搜索,
如果找不到就去内置命名空间中查找,如果找到就返回内容,
如果找不到,就报错

(2)如果一开始就从全局命名空间中查找,就直接找全局命名空间中的内容
如果找到则停止搜索,如果找不到就从内置空间中查找。

(3)注意事项:
自己的变量名称不要和内置的变量名相同,否则不能使用内置命名空间中的函数功能。

def func():
id = 20
print(id
func()
print(id)

运行结果:

 20
    <built-in function id>

在这里插入图片描述

注意事项:自己的变量名不要个内置命名空间中的函数名相同。
否则无法使用内置函数功能。

# a = 10
# id = 20
# print(id(a))   #报错

在这里插入图片描述

嵌套函数的情况:
1、先在当前 (嵌套的或 lambda) 函数的命名空间中搜索
2、然后是在父函数的命名空间中搜索
3、接着是模块命名空间中搜索
4、最后在内置命名空间中搜索
在这里插入图片描述

二、作用域:
1、作用域:指的是变量的可用范围
2、根据变量声明的位置不同,作用可分为4类:
局部作用域---->函数体中声明的变量
嵌套作用域---->嵌套函数中外层函数体中声明的变量
全局作用域---->py文件中声明的作用域
内置作用域---->python提供的变量(函数)
3、变量的搜索顺序:
先从当前作用域查找,如果找到则停止搜索,如果找不到,就往
上一层作用域中查找。依次类推,如果找不到就报错。

b=20  #b变量声明在了全局作用域,因此可以在全局作用域使用
def func():
    a=10
    #a变量在局部作用域中
    #a变量的作用范围就是整个函数体
    print(a)
    print(b)  #可以作用在局部作用域中

func()
# print(a)   #报错,因为a变量已经出了自己的作用域范围。
print(b)    #可以正常运行



c=30
def outter():
    a=10
    def inner():
        b=20
        print(b)
        print(c)#访问全局作用域中的内容  #30

        print(a)#访问嵌套作用域的内容   #10
    #print(b)  #报错,b出了自己的范围,嵌套作用域范围无法访问局部作用域范围的变量
    inner()
outter()
print(c)         #30    #全局作用域范围访问全局作用域范围
#print(a)  #报错,全局作用域范围不能访问嵌套作用域范围内的变量

在这里插入图片描述

变量的搜索顺序:

a=1
def outter():
    a=10
    def inner():
        a=20
        print(a)  #20.10.1
    inner()
    print(a)  #10,1
outter()
print(a)  #1

在这里插入图片描述

三、全局变量和局部变量
在函数中定义的变量称为局部变量,只在函数内部生效,
在程序一开始定义的变量称为全局变量,全局变量的作用域是整个程序。

全局变量:在函数中定义的变量称为局部变量,只在函数内部生效.
局部变量:在程序一开始定义的变量称为全局变量,全局变量的作用域是整个程序.

name='zs'   #全局变量
def func():
    name='ls'  #局部变量
    print(name)    #ls
func()

a=10
lst=[12,3]
def func(c,lst1):
    c=20
    lst1.append(4)
    print(c,lst1)

func(a,lst)
print(a,lst)

运行结果:

20 [12, 3, 4]
10 [12, 3, 4]

global:关键字可以将局部变量变成一个全局变量。
nonlocal:关键字只能修改嵌套外层(非全局)变量。

global关键字:

a = 10
print(id(a))


def func():
    global a  # 变成了全局变量
    a = 20  # 修改全局变量的值
    print(id(a))  # id 相同
    print(a)


func()
print(a)

运行结果:

505900656
20
20

nonlocal关键字:

def outter():
    name='zs'
    def inner():
        nonlocal name   #和outter中的name是同一个变量
        name='赵四'
        print(name)   #赵四
    inner()
    print(name)      #赵四
outter()

yunxingjieg:

  赵四
  赵四

在这里插入图片描述

四、命名空间和作用域的关系
命名空间定义了在某个作用域内变量名和绑定值之间的对应关系,命名空间是键值对的集合,变量名与值是一一对应关系。作用域定义了命名空间中的变量能够在多大范围内起作用。

猜你喜欢

转载自blog.csdn.net/weixin_44239541/article/details/85796708