进阶函数

一、函数对象

函数是第一类对象:函数名指向的值可以被当做参数传递

1.函数名可以被传递

def func():
    print('func')

f = func  # 函数名可以当做变量名
print(f)  # f指向的也是函数func指向函数体代码的内存地址

 

2.函数名可以被当做参数传递给其他参数

def func():
    print('from func')

def index(args):
    print(args)
    args()  # from func
    print('from index')
index(func)  #把func这个函数名传递给args,打印出来的结果为:<function func at 0x0000028A85681F28>
             #from index

 

3.函数名可以被当作函数的返回值

def index():
    print('index')


def func():
    print('func')
    return index
res = func()  # func
print(res)  # 函数名的内存地址:<function index at 0x000001E573521F28>
res()  # 返回值:index

 

4.函数名可以被当作容器类型的参数

def func():
    print('func')  # func
print(func())  # None
l = [1,2,func,func()]  # func  
print(l)  # [1,2,<function func at 0x000001F7D79899D8>,None

 

 

二、函数嵌套

1.函数嵌套的调用

在函数内部调用其他函数
可以将复杂的逻辑简单化

# def max2(x,y):
#     if x > y:
#         return x
#     else:
#         return y

# def max3(x,y,z):
#     res1=max2(x,y)  # 先比较x和y的值
#     res2=max2(res1,z)  # 较大的值与z进行比较
#     return res2  # 返回较大的值
# print(max3(7,8,9))

2.函数嵌套的定义

def outer():
    x = 1
    print('outer')
    def inner():
        print('inner')
    # print(inner)
    return inner

res = outer()  # outer
print(res)  # <function outer.<locals>.inner at 0x000001F19F822AE8>
res()  # inner

 

三、名称空间

存放的是变量名与变量值的内存地址的绑定关系的地方

想要访问一个变量的值,必须先去名称空间拿到对应的名字,才能够访问变量的值

1.名称空间的分类

1》内置名称空间:python解释器提前给你定义好的名字(已经存放在内置名称空间),如len,max

2》全局名称空间:文件级别的代码(if for while 无论嵌套多少层,它们内部所创建的名字都是全局名称空间)

3》局部名称空间:函数体内创建的名字都属于局部名称空间

 

2.生命周期

内部名称空间:只要python解释器已启动立马创建,关闭python解释器的时候内置名称空间自动销毁

全局名称空间:只要右键运行py文件会自动创建,py文件程序运行结束自动销毁

局部名称空间:函数调用的时候自动创建,函数指向结束立即销毁(动态创建动态销毁)

 

3.名字查找的顺序

1》站在全局的角度:全局>内置

2》站在局部的角度:局部>全局>内置

x = 1
def f1():
    x = 2
    def f2():
        x = 3
        def f3():
            x = 4
            def f4:
                x = 5
                print(x)
            f4()
        f3()
    f2()
f1()

#当需要调用f1的时候,会站在f4的局部去取值,如果f4没值就会取f3的值,按照局部>全局>内置这个顺序去取值

注意:

函数在定义阶段查找名字的顺序就已经固定了 不会因为函数的调用位置变化

 

 

四、作用域

1.全局作用域

                    全局有效:内置名称空间  全局名称空间

2.局部作用域

                   局部有效 : 局部名称空间

3.glolal

在局部修改全局的变量,如果需要修改多个,用逗号隔开

x = 1

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

#首先,调用函数func在全局名称空间,所以要站在全局名称空间这个角度去看,就不需要考虑
#局部名称空间了,全局有 x = 1 这个数,所以打印结果就为1



#如果就要将打印结果变为局部 x = 2这个数呢?该怎么操作?
x = 1

def func():
    global x  # 在局部修改全局的变量
    x = 2
func()
print(x)  # 2

 

4.nonlocal

在局部修改局部的变量,如果想修改多个,用逗号隔开

def func():
    x = 1
    def index():
        nonlocal x  # 局部修改局部
        x = 2
    index()
    print(x)
func()  # 2

 

posted @ 2019-07-10 20:10  小青年て  阅读(278)  评论(0编辑  收藏  举报