欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

python语法之函数对象/嵌套/名称空间/作用域

程序员文章站 2023-10-29 10:41:10
一、函数对象 1、 函数名是可以被引用的 def foo(): print('from foo') res = foo #把函数名foo给了res,res和foo指向了同一个内存地址 res() #from foo 2、函数名可以当做参数传递 def foo1(a,b): #a=1,b=foo2 p ......

一、函数对象

1、 函数名是可以被引用的

def foo():
    print('from foo')
res = foo   #把函数名foo给了res,res和foo指向了同一个内存地址
res()   #from foo

2、函数名可以当做参数传递

def foo1(a,b):  #a=1,b=foo2
    print(a)     #1
    b()        #b() 即foo2() 去执行foo2()的函数,结果:from foo2
def foo2():
    print('from foo2')
foo1(1, foo2)   #foo2作为参数传给了b

3、函数名可以当做返回值使用

def foo(x):
    return x
def foo1():
    print('from foo1')
res = foo(foo1)   #把函数名foo1给了x,调用foo()函数返回foo1,然后把foo1给了res
res()  #res() 即是foo1()

4、函数名可以当做容器类型的元素

def func():
    print('from func')
l1 = [1,'2',func]
l = l1[2]   #即l=func
l()       #func()

4.1、购物车:

func_dic = {
    '1': register,
    '2': login,
    '3': shopping,
    '4': pay
}

def main():
    while true:
        print("""
            1、注册
            2、登录
            3、购物
            4、付款
            5、退出
        """)
        choice = input("请输入对应的编号:").strip()
        if choice == '5':
            break
        if choice not in func_dic:
            continue
        else:
            func_dic[choice]()

main()

 

二、函数的嵌套

2.1、函数的嵌套调用:在函数内调用函数

2.2、函数的嵌套定义:在函数内部定于函数

 

三、名称空间

3.1、名称分类

3.1.1、内置名称空间:python提前给定好的名字,比如内建函数名len,print。

3.1.2、全局名称空间:存放于文件级别的名字,顶格的名称。

3.1.3、局部名称空间:函数内部定义的名字。

 

3.2、名称空间的生命周期

3.2.1、内置名称空间:伴随着python解释器的启动而产生,关闭而回收。

3.2.2、全局名称空间:伴随着pytho文件的开始执行而产生,执行完毕而回收。

3.2.3、局部名称空间:伴随着函数的调用而产生,函数结束调用而回收。

 

3.3、名称空间的顺序

加载顺序:内置名称空间 > 全局名称空间 > 局部名称空间

查找顺序:局部名称空间 > 全局名称空间 > 内置名称空间

# 函数内部使用的名字,在定义阶段就已经规定死了,与你的调用位置无关

def func1():
    x = 2
    def func2():
        x = 3
        print('func2:', x)
    func2()
    print('func1:', x)
func1()

 

四、作用域

4.1、分类

4.1.1、全局作用域

位于全局名称空间、内置名称空间中的名字属于全局范围。该范围内的名字全局存活、全局有效(在任意位置都可以使用)。

4.1.2、局部作用域

位于局部名称空间的名字属于局部范围。该范围内的名字临时存活(即在函数调用时临时生成,函数调用结束后就释放)、局部有效(只能在函数内使用)。

 

4.2、作用域与名字查找优先级

4.2.1、在局部作用域查找名字时,起始位置是局部作用域,所以先查找局部名称空间,没有找到,再去全局作用域查找:先查找全局名称空间,没有找到再查找内置名称空间,最后没找到抛出异常。

x = 1
def foo2():
    x = 2
    def foo3():
        x = 3
        print(x)  #x=1
    foo3()
foo2()

 

4.2.2、在全局作用域查找名字时,起始位置时全局作用域,所以先查找全局名称空间,没有找到再查找内置名称空间,最后没找到抛出异常。

x = 1
def foo2():
    x = 2
foo2()
print(x)  #1  

#4.2.3、python支持函数的嵌套定义,在内嵌的函数查找名字时,会优先查找自己局部作用域的名字,然后由内而外一层层查找外部嵌套函数定义的作用域,都没有找到,则查找全局作用域。

x = 1 def foo(): x = 2 def foo1(): x = 3 def foo2(): # x = 4 def foo3(): x = 5 print('foo3:',x) #5 foo3() print('foo2:',x) #4 foo2() print('foo1:',x) #3 foo1() print(x) #2 foo()
#在函数内,无论嵌套多少层,都可以查看到全局作用域的名字,若要在函数内修改全局名称空间的名字值,需要用到global关键字

x = 1 def foo2(): global x x = 2 foo2() print(x) #2
#nonlocal

x = 1
def foo2():
    x = 2
    def foo3():
        nonlocal x
        x = 3
        print(x)  x=3 
    foo3()
foo2()