第十天 函数的嵌套与定义 名称空间 作用域

1 函数定义的三种方式

1空函数

2无参函数

有参函数

2 命名关键字传参

在函数定义的期间,放在*args与**kwasgs之间的参数叫做命名关键字传参

def func(x,y=1,*args,z=3,m,**kwargs):  #感觉z默认参数,m是位置参数,z放在了m的前面,其实他们都是命名关键字参数
    print(x,y)
    print(args)
    print(z,m)
    print(kwargs)
func(1,2,1,2,3,4,5,6,7,78,8,9,0,z=69,m=999,o=666999,l = 999666)

3 函数对象

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

第一种情况;函数名被变量传递

name = 'jason'
x = name
print(name,id(name))
print(x,id(x))
def func():
    print('from func')
print(func)
print(id(func))
f = func
print(f)
print(id(f))
func()
f()  # 其实此时的f也是指向的是func的函数代码体的内存地址,所以f加括号可以调用函数

第二种情况;函数名可以当做实参,传递给其他函数

def index():
    print("index")

def func(args):
    print("func")
    args()

func(index)
# 注意,如果你传入的函数名定义在调用函数的下面
#会报错

第三种情况;函数名可以当做函数的返回值

def func():
    print("func")
    
    
def index():
    print("index")
    return func

ret = index()  # 注意此时index()这个函数已经被调用,返回值就是上一个函数的函数名
ret()  # 拿到这个返回值就可以调用func的这个函数

第四种情况;可以当做容器类型的参数

下面两种代码风格的不同,导致了代码的行数加多

第一种如果每一次加入了一项功能,就要再多写一个函数

并且,还要多谢写一个控制语句,很麻烦

但第二种我们就不需要写控制语句

我们只需要将函数与用户想要输入的对应起来,将函数的

函数名一一对应加入到列表中去就可以了

如果下一吃还要加功能,那就只需要加一个函数,然后在将字典中加入一个

函数对应的字符就可以了

def func():
    print("func")

def index():
    print("index")

def info():
    print("info")

while True:
    choose = input("请输入你想要的功能")
    if choose == "1":
        func()
    elif choose == "2":
        index()
    elif choose  == "3"
        info()
    else:
        print("你输入的功能还没有开发,敬请期待")
def func():
    print("func")

def index():
    print("index")

def info():
    print("info")

msg = {"1":func,"2":index,"3":info}

while True:
    choose = input("请输入你想要的功能")
    if choose in msg:
        msg.get(choose)()
    else:
        print("你输入的功能还没有开发,敬请期待")

4 函数的调用嵌套

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

基本格式

def func():
    print("func")


def index():
    print("index")
    func()


index()

比较4个数字的大小

def my_max2(x,y):
    if x > y:
        return x
    return y

def my_max4(a,b,c,d):
    res1 = my_max2(a,b)  # 注意此时的 a,b 是变量 在调用my_max4的时候回赋值给他,它会继续赋值给他的函数体x,y
    res2 = my_max2(res1,c)
    res3 = my_max2(res2,d)
    return res3

a = my_max4(1,22,88,44)
print(a)

5 函数嵌套定义

注意,如果info这个函数在调用函数的下方,会报错。错误是没有定义就使用了

def info():
    print("info")


def func():
    print("func")
    def index():
        print("index")
        return info

    return index

ret = func()
a = ret()
a()

6 名称空间

就是存放变量名与变量值地址绑定关系的的空间

想访问一个变量值,就必须到名称空间找到变量地址对应的变量名字

名称空间分为3种

第一种;内置名称空间

就是Python解释器提前给你定义好的名字

第二种;全局名称空间

文件级别的代码 if while for无论循环多少层都是全局名称空间的

第三种;局部名称空间

函数体内定义的创建出来的名字都是局部变量

生命周期

内置名称空间,当Python解释器运行就会自动创建,关闭Python解释器就UI自动销毁

全局名称空间,当Python文件运行就会自动创建,关闭文件就会自动销毁

局部名称空间,当创建函数是就会自动创建,函数结束时就会自动销毁

7 名称空间查找顺序

查找顺序(需要确定你现在站在哪里****)

1 站在全局;全局>>>内置

2 站在局部;局部>>>全局>>>内置

记忆方法;(自下而上)

例1

x = 111
def f1():
    # x = 222
    def f2():
        # x = 333
        def f3():
            # x = 444
            def f4():
                # x = 555
                print(x)
            # x = 777  # 纯粹为了教学演示
            f4()
        # x = 777  # 纯粹为了教学演示
        f3()
        # x = 888
    f2()
    # x = 999
x = 1221212
f1()
# x =88888

解析;

如果 x 在函数f4里面,(这里的里面就是指在函数定义和函数调用之间)我们的x是能答应出来的

如果是x没在函数f4里面他就会去他的上一层函数去找,如果有就会答应x的值,如果有多个就就会打印最后的一个的值

如果在在f4调用函数的下面就会报错。没有定义的变量

例2

def func():
    # x = 1
    def index():
        print(x)  # 获取全局找x
    return index

res = func()
# x = 999
res()
# x = 999

解析;

第一步,判断x是否在函数index中,如果没有就会去上一层函数中找

如果还是没有就继续上一层中找

在上一层就是全局名称空间

如果有就打印,如果么有就会报错

例3

x=111
def outer():
    def inner():
        print('from inner',x)
    return inner
f=outer()
x = 222
f()

解析

x先是在自己函数中找,没有,就到了上一层找

上一层也没有,就到了全局名称空间找

然后x=111,到x=222取到的是222

例4

x=111
def outer():
    def inner():
        print('from inner',x)
    return inner
f=outer()
def func():
    x=333
    f()
func()

解析

x先是在自己函数中找,没有,就到了上一层找

上一层也没有,就到了全局名称空间找

然后x=111,取到111,他不会去下一个函数找,遵循,局部名称空间>>>到全局空间 名称空间>>>到内置空名称空间

列5

x=111
def outer():
    def inner():
        # x = 888888
        print('from inner',x)
        x = 66666666
    return inner
f=outer()
f()

解析;

此时的x会报错

变量必须先定义,在使用

终极x的位置分析

# x = 700
def func():
    # x = 100
    def index():
        # x = 200
        def info():
            # x = 300
            print(x)
            # x = 800
        # x = 400
        info()
        # x = 900
    # x = 500
    index()
    # x = 1000
# x = 600
func()
x = 100

8 作用域

global 和 nonlocal

global 在局部修改全局的不可变类型数据

username = 'jason'
def func():
    # x.append('嘿嘿嘿')
    global x,username  # 修改全局变量 而不是创建局部名称空间
    x = 999
    username = 'egon'
func()
print(x)
print(username)

 nonlocal 局部修局部

def func():
    x = 1
    def index():
        nonlocal x
        x = 2
    index()
    print(x)
func()

 

猜你喜欢

转载自www.cnblogs.com/cherish937426/p/11165793.html
今日推荐