Python的进阶函数

多参数解析

使⽤ *args 和 **kwargs 来调⽤函数。

def res(arg1, arg2, arg3):
    print("arg1:", arg1)
    print("arg2:", arg2)
    print("arg3:", arg3)

使用普通参数方式:

res(1, 2, 3)

使用*args非关键字可变参数方式:

#   使用`*args`非关键字可变参数方式:
# 以元祖方式传递
# *args是一种用于函数定义的语法,
# 它允许你向函数传递任意数量的非关键字参数。
# 这些参数在函数内部作为一个元组(tuple)存在。
# 使用*args时,你可以将多个参数以元组的形式传递给函数,
# 然后在函数内部对这些参数进行操作
nums  = (1,2,3)
res(*nums)

使用**kwargs关键字可变参数方式:

#   使用`**kwargs`关键字可变参数方式
# 以字典方式传递
# **kwargs是一种用于函数定义的语法,
# 它允许你向函数传递任意数量的关键字参数。
# 这些参数在函数内部作为一个字典(dictionary)存在。
# 使用**kwargs时,你可以将多个参数以关键字参数的形式传递给函数,
# 然后在函数内部对这些参数进行操作
kwargs = {
    "arg1": 1,
    "arg2": 2,
    "arg3": 3
}
res(**kwargs)

如果你想在函数⾥同时使⽤所有这三种参数, 顺序是这样的:

func(fargs, *args, **kwargs)

闭包

如果在一个函数的内部定义了另一个函数,外部的我们叫他外函数内部的我们叫他内函数。

  • 闭包函数:声明在一个函数中的函数,叫做闭包函数。

示例一:无返回值情况

#   示例一:无返回值情况
#这段代码中并没有调用 say 函数,所以它不会执行任何操作
#外部函数
def hello():
    #内部函数
    def say():
        print("hello python")
    # 这里是在 hello 函数内部调用 say 函数:
#    say()
hello()

注意:hello代表函数本身;hello()代表函数的返回值。

示例二:有返回值情况

#   示例二:有返回值情况
#外部函数
def hello():
    #内部函数
    def say():
        print("hello python")
    #这里返回的是内部函数本身
    return say
#此时,res 变量持有 hello 函数返回的 say 函数的引用
res = hello()
#由于 hello 函数返回的是内部函数 say,
# 而不是一个具体的值或执行任何操作,
# 所以直接调用 hello() 将不会打印任何内容,
# 因为返回的 say 函数并没有被调用
hello()
#想打印内容的话直接运行res(),因为 res 已经持有 say 函数的引用
#res()

注意:此时可以发现hello()方法的返回值是say方法,也就是它的内部函数。

  • 闭包:在一个外函数中定义了一个内函数,内函数里运用了外函数中声明的参数或变量,并且外函数的返回值是内函数的引用。这样就构成了一个闭包。

def outer(a):
    def inner(b):
        return a+b
    return inner

函数inner就被包括在函数outer内部,这时outer内部的所有局部变量,对inner都是可见的。但是反过来就不行,inner内部的局部变量,对outer就是不可见的。所以,父对象的所有变量,对子对象都是可见的,反之则不成立。


# 获取最外层的outer方法的返回值:inner
# 调用outer函数并传入参数4,返回inner函数的引用
res = outer(4)
# 调用res,即调用inner函数,并传入参数6
print(res(6))#最后输出结果为10

注意:外层函数的变量将持久地保存在内存中。

装饰器

装饰器是闭包的一种应用。装饰器就是用于拓展原来函数功能的一种函数,这个函数的特殊之处在于它的返回值也是一个函数,使用装饰器的好处就是在不用更改原函数的代码前提下给函数增加新的功能。

# 开启事务
核心业务处理
# 提交/回滚事务

可以理解为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__)

示例二:带参数的装饰器

装饰器中可以传入参数,先形成一个完整的装饰器,然后再来装饰函数,当然函数如果需要传入参数也 是可以的,用不定长参数符号就可以接收。

def logging(level='debug'):
    print(level)
    def outer_wrapper(func):
        def inner_wrapper(*args, **kwargs):
            print(f"{level}: enter {func.__name__}()")
            return func(*args, **kwargs)
        return inner_wrapper
    return outer_wrapper
    
@logging("info")
def hello():
    print("hello python")
​
hello()

注意:@logging装饰器带括号和不带括号的区别。

  1. @logging不带括号,hello方法名作为参数传入,则在level参数接收到的是hello方法;

  2. @logging()带括号,则使用logging中的level默认参数或者传入参数覆盖level默认参数;

def logging(logfile='out.txt'):
    def decorator(func):
        def wrapped_function(*args, **kwargs):
            log_string = func.__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()

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值