多参数解析
使⽤ *args
和 **kwargs
来调⽤函数。
def res(arg1, arg2, arg3): print("arg1:", arg1) print("arg2:", arg2) print("arg3:", arg3)
使用普通参数方式:
res(1, 2, 3)
使用*args
非关键字可变参数方式:
# 以元祖方式传递 nums = (1, 2, 3)
使用**kwargs
关键字可变参数方式:
# 以字典方式传递 kwargs = { "arg1": 1, "arg2": 2, "arg3": 3 } res(**kwargs)
如果你想在函数⾥同时使⽤所有这三种参数, 顺序是这样的:
func(fargs, *args, **kwargs)
闭包
如果在一个函数的内部定义了另一个函数,外部的我们叫他外函数,内部的我们叫他内函数。
-
闭包函数:声明在一个函数中的函数,叫做闭包函数。
示例一:无返回值情况
def hello(): def say(): print("hello python")
注意:hello代表函数本身;hello()代表函数的返回值。
示例二:有返回值情况
def hello(): def say(): print("hello python") return say
注意:此时可以发现hello()方法的返回值是say方法,也就是它的内部函数。
res=hello hello()
-
闭包:在一个外函数中定义了一个内函数,内函数里运用了外函数中声明的参数或变量,并且外函数的返回值是内函数的引用。这样就构成了一个闭包。
def outer(a): def inner(b): return a+b return inner
函数inner就被包括在函数outer内部,这时outer内部的所有局部变量,对inner都是可见的。但是反过来就不行,inner内部的局部变量,对outer就是不可见的。所以,父对象的所有变量,对子对象都是可见的,反之则不成立。
# 获取最外层的outer方法的返回值:inner res = outer(5) print(res(6))
注意:外层函数的变量将持久地保存在内存中。
装饰器
装饰器是闭包的一种应用。装饰器就是用于拓展原来函数功能的一种函数,这个函数的特殊之处在于它的返回值也是一个函数,使用装饰器的好处就是在不用更改原函数的代码前提下给函数增加新的功能。
# 开启事务 核心业务处理 # 提交/回滚事务
可以理解为Spring中的AOP。
示例一:初识装饰器
def Transaction(func): def wrapper(): print("开启事务处理") func() print("提交事务处理") return wrapper @Transaction def hello(): print("hello python") hello() print(hello.__name__)
注意:当使用装饰器@Transaction修饰方法时,
hello.__name__
返回的方法名称就不是当前hello方法了,而是被装饰器中的wrapper方法所取代。
@wraps(func)
的作用: 不改变使用装饰器原有函数的结构
from functools import wraps def Transaction(func): @wraps(func) def wrapper(): print("开启事务处理") func() print("提交事务处理") return wrapper @Transaction def hello(): print("hello python") hello() print(hello.__name__)
示例二:带参数的装饰器
装饰器中可以传入参数,先形成一个完整的装饰器,然后再来装饰函数,当然函数如果需要传入参数也 是可以的,用不定长参数符号就可以接收。当使用hello()时@debug_decorator()会把它变成参数func插入wrapper函数中
def debug_decorator(mode='debug'): # 打印传入的参数 mode print(mode) # 定义内部函数 wrapper,接受一个参数 func def wrapper(func): # 定义内部函数 inner_wrapper def inner_wrapper(): # 打印调试信息,包括 mode 的值和传入的函数名 print(f"{mode}: entering {func.__name__}()") # 调用传入的函数 func func() # 返回内部函数 inner_wrapper return inner_wrapper # 返回内部函数 wrapper return wrapper # 使用装饰器定义函数 hello,并传入参数 @debug_decorator() def hello(): print("12312") hello() # 调用函数 hello
注意:@logging装饰器带括号和不带括号的区别。
@logging不带括号,hello方法名作为参数传入,则在level参数接收到的是hello方法;
@logging()带括号,则使用logging中的level默认参数或者传入参数覆盖level默认参数;
def logging(logfile='out.txt'): def decorator(func): def wrapped_function(*args, **kwargs): from datetime import datetime current_time = datetime.now() String_log ="当前时间:"+str(current_time)+ c2.__name__ +"调用" # 打开logfile,并写⼊内容 with open(logfile, 'a') as opened_file: # 现在将⽇志打到指定的logfile opened_file.write(log_string + '\n') return wrapped_function return decorator @logging() def hello(): pass hello()
此方法用于创建日志查看函数是否被使用