【python学习笔记】34:函数参数、闭包、lambda函数、装饰器、偏函数

版权声明:本文为博主原创学习笔记,如需转载请注明来源。 https://blog.csdn.net/SHU15121856/article/details/82942139

函数参数

位置参数

一般写的函数调用按顺序传入参数,这种参数就是位置参数,即通过位置来知道这个参数是传给哪个参数的。

pow(x,n)

默认参数

即为参数设定默认值,具有默认值的参数可以不传入,所以必选参数在前,默认参数在后

廖老师提到"变化大的参数放前面,变化小的参数放后面",但我觉得还是要视函数各个参数的实际意义和语义来考虑。

pow(x,n=2)

默认参数必须指向不变对象,因为默认参数的值在函数定义时就设定好了,如果改变了默认参数所指向的对象的内容,下次再调用时默认参数就是改变之后的了。

廖老师的例子中使用[]空列表作为默认参数,在添加元素后这个对象就改变了,后来改成不变对象None并在使用前判断是否是None,如果是(表明使用了默认参数)再去使用空列表即可。

可变参数

符号*放在函数形式参数前表示使用了可变参数,即可以传入任意个参数;放在列表或者元组前表示序列解包,可以用这种方式将其元素依次传入可变参数中。

def cal_sum(base, *num):
    s = 0
    for n in num:
        s += n * base
    return s


print(cal_sum(2, 2, 3))  # base=2,num=(2,3),结果是10

a = [2, 2, 3, 4]
print(cal_sum(*a))  # 序列解包再传入.base=2,num=(2,3,4),结果是18

关键字参数

可变参数将传入的任意多个普通参数组织成tuple,而关键字参数将传入的任意多个k-v参数对组织成dict,关键字参数在函数的形参前使用**来指示。

def fun(c1, c2, **c):
    print('c1:', c1, ',c2:', c2, ',c:', c)


fun(1, 2, c3=3, c4=4, c5=5)  # c1: 1 ,c2: 2 ,c: {'c3': 3, 'c4': 4, 'c5': 5}

命名关键字参数

前面的关键字参数可以传入任意多的任意的合法的k-v对,使用命名关键字参数可以限制哪些关键字是要传入的。

命名关键字参数放在参数表靠后的位置,但在关键字参数之前,与之前的参数用一个*参数隔开。

def fun(c1, c2, *, c3, c4, c5):
    print('c1:', c1, ',c2:', c2, ',c3:', c3, ',c4:', c4, ',c5', c5)


fun(1, 2, c3=3, c4=4, c5=5)  # c1: 1 ,c2: 2 ,c3: 3 ,c4: 4 ,c5 5

参数定义的顺序

必选参数、默认参数、可变参数、命名关键字参数、关键字参数。

闭包

在函数内部可以定义函数,并将其返回,以实现惰性求值的特性。当内部函数被保存到外部时就形成了闭包。

def createCounter():
    a = 0

    def counter():
        nonlocal a  # 指示a不是本地的,要到内部函数之外去找
        a += 1
        return a

    return counter


if __name__ == '__main__':
    counterA = createCounter()
    print(counterA(), counterA(), counterA(), counterA(), counterA())  # 1 2 3 4 5

廖老师也没说闭包有什么用,反正就给了一个引用循环变量的例子,可变的变量在内部函数里反复返回之后,最后调用时全都是最终的那个值,可以再加一个中间的函数,专门用来传当前的值。

lambda函数

匿名函数,方便使用,也可以通过赋值到变量上来配备函数名。

print(list(map(lambda x: x / 2, [1, 2, 3, 4])))  # [0.5, 1.0, 1.5, 2.0]

装饰器

装饰器(Decorator)有点像Java注解配置切面一样,可以拿来打日志之类的,自定义一个函数,内部函数名为wrapper并在里面调用要修饰的函数即可。

# 定义一个打日志的装饰器
def logger(fun):
    def wrapper(*args, **kwargs):  # 适应多参数
        print("函数", fun.__name__, "启动前")
        fun(*args, **kwargs)  # 调用要修饰的函数
        print("函数", fun.__name__, "启动后")

    return wrapper


@logger  # 把装饰器挂在要修饰的函数上
def sayHi():
    print("Hi~")


sayHi()

输出:

函数 sayHi 启动前
Hi~
函数 sayHi 启动后

偏函数

functools.partial定义一个偏函数,即将函数的某些参数固定住,返回一个新的函数,为其命名以方便使用。

import functools

int2 = functools.partial(int, base=2)

print(int2('1110'))  # 使用刚定义的偏函数
print(int('1110', base=2))  # 等价于这个,结果都是14

猜你喜欢

转载自blog.csdn.net/SHU15121856/article/details/82942139