python学习笔记(四)函数

这篇博客深入探讨了Python编程中的关键概念,包括函数的定义与调用、嵌套函数及作用域、闭包的原理与自由变量、装饰器的使用以及如何实现非功能性拓展。还介绍了lambda表达式的简洁语法和生成器的功能,特别是yield关键字如何保留函数状态。此外,文中还提到了多个装饰器的执行顺序及其工作原理。
摘要由CSDN通过智能技术生成

思维导图,个人制作,不一定准确
注:这个思维导图只是学习的时候随手制作的,不一定准确

一般的函数定义和调用

def func(arg1,arg2):  #参数无需声明数据类型
	res = arg1 + arg2
	return res   #这是返回值

res = func(1,2)
print(res)

嵌套函数

def func(x,y):
	print("x+y=")
	def add(x,y):  #在外部不能直接调用,必须通过func进行调用
		return x+y
	return add(x,y)
print(func(1,2))

变量的作用范围可以辐射到同级的函数内部

变量的使用是就近原则,先使用局部变量,若添加global关键字则是先使用外部变量

# 变量的作用范围可以辐射到同级的函数内部
x = 1
y = 2
def add():
	return x+y
print(add())   # 3
#变量的使用是就近原则,先使用局部变量,若添加global关键字则是使用全局变量
x = 1
y = 2
def func():
	x=-1
	print(x)  # -1
	global y  #注意:声明全局前不能使用该变量
	print(y) # 2
	y = -2

func()
print("调用函数后:")
print(x)  #1
print(y) #-2

闭包

定义:闭包是词法闭包的简称,是引用自由变量的函数。则个被引用的自由变量将和这个函数一同存在,及时已经离开了创造它的环境也不例外。就是说只要外界的变量仍然有函数内的引用,则该变量不会被回收。
自由变量:不在本个代码块中定义的变量。代码块:同函数或缩进中同缩进的语句
nonlocal关键字修饰自由变量可以修改其本身的值,该关键字只能在闭包中使用
判断是否闭包:
1.函数返回值是否为一个函数名且该函数是嵌套在本函数中 且 返回值涉及的函数的返回值是否使用了自由变量
2.是否有__closure__ 属性,其包含了闭包函数保存的自由变量

def checkClosure(func,*arg):
    '''
    功能:检查函数是否为闭包,若是则打印自由变量的值
    参数:
        func: 闭包的函数名
         *arg: 可选:func的参数
    '''
    if hasattr(func(*arg),"__closure__"):
        if func(*arg).__closure__!=None:
            print(func.__name__ + "保存的自由变量为:")
            for i in func(*arg).__closure__:
                print(i.cell_contents)
        else:
             print(func.__name__+"闭包不存有自由变量")
    else:
        print(func.__name__+"不是闭包")
def checkClosure(func,*arg):
    '''
    功能:检查函数是否为闭包,若是则打印自由变量的值
    参数:
        func: 闭包的函数名
        *arg: 可选:func的参数
    '''
    if hasattr(func(*arg),"__closure__"):
        if func(*arg).__closure__!=None:
            print(func.__name__ + "保存的自由变量为:")
            for i in func(*arg).__closure__:
                print(i.cell_contents)
        else:
             print(func.__name__+"闭包不存有自由变量")
    else:
        print(func.__name__+"不是闭包")

def func(arg1,arg2):
    val = 3 
    def func2():
        # arg1,arg2,val都是自由变量
        return arg1+arg2+val
    return func2  # 返回内嵌函数名
print(func(2,3)())  # 8

checkClosure(func,5,6) # 5 6 3

装饰器

功能:在不改变原代码的情况下为函数增加非功能性的拓展功能,如插入日志,增加提示语句等。

#修饰器:参数是一个函数名
def dec(func):
    def wrapper(arg1,arg2):   #参数和原功能函数的参数相同
        print(arg1,"+",arg2,"=",end=" ")
        val = func(arg1,arg2)
        print(val)
        return val
    return wrapper
    
@dec   #在原功能函数上方加 @修饰器名
def add(arg1,arg2):   
    return arg1+arg2

#原调用代码
add(1,2)

我暂时不太懂的地方:多个修饰器的执行顺序。以下例子的输出是:
dec
dec2
两数相加得:1 + 2 = 3
3

#非功能装饰
def dec(func):
    print("dec")
    def wrapper(arg1,arg2):
        print(arg1,"+",arg2,"=",end=" ")
        val = func(arg1,arg2)
        print(val)
        return val
    return wrapper

def dec2(func):
    print("dec2")
    def wrapper(arg1,arg2):
        print("两数相加得:",end="")
        val = func(arg1,arg2)
        print(val)
        return val
    return wrapper

@dec2
@dec   #在原功能函数上方加 @修饰器名
def add(arg1,arg2):   
    return arg1+arg2

add(1,2)

lambda表达式

目前所学的就像是对那些公式函数(只需写参数和返回值,没必要写函数体的函数)的简写方式
lambda 参数表:返回值

f = lambda x,y:x+y
print(f(1,2)) # 3

生成器

注:本知识点书上似乎没有,配套的教学视频才有
生成器就是使用yield关键字代替returnyield可以保留函数的状态(就是说函数调用后不会被清除)
使用:
1.使用 next()方法,获取一次返回值
2.使用for循环获取剩余的所有返回值

def yie():
    for i in range(10):
        yield i  #在下次调用时会从下一句开始,继续执行
        i = i+1

#直接调用是返回生成器的引用
res = yie()
print(res)

#使用next()获取生成器的返回值
print(next(res)) # 0

#使用for循环获取生成器的返回值
for i in res:
    print(i) #1~9
def yie():
    for i in range(10):
        yield i  #在下次调用时会从下一句开始,继续执行
        i = i+1

#直接调用是返回生成器的引用
res = yie()
print(res)  #res是生成器对象的复制

# 使用next()方法获取生成器的返回值
print(next(res)) # 0
print(next(res)) # 1

print(next(yie())) # 0  标记1
#使用for循环获取生成器的返回值
print("for循环:")
for i in yie():  #这个生成器对象不是“标记1”的相同对象
    print(i)  # 0~9
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值