Python中关于“闭包、装饰器”的学习

目录

一、闭包

二、装饰器

1.通过_不带参数的装饰器_用于运算

2.通过_带参数的装饰器_区分成绩

3.通过_多个装饰器_登录应用

4.通过_装饰器带返回值函数_判断质数

三、关于序列的常见内置函数

1、map函数

2、zip函数

3、filter函数


一、闭包

闭包是一种特殊的函数,而函数是一段可以重复使用的代码,它可以接受输入(参数),并返回输出(结果)。

闭包不仅包含函数的代码,还包含了函数定义时所在的环境。这个环境包括当时的作用域中的变量。闭包不仅可以访问它自己的参数,它所在的环境中的变量,也可以访问它所在的环境的外部变量。

闭包通常是在嵌套函数中出现的(嵌套函数,理解为:在一个函数内部定义了另一个函数)。内层函数可以访问外层函数的变量,这就是闭包的作用所在。

闭包的一个重要特性是它可以记住并访问它被定义时的环境,即使它在当前环境之外被调用。这意味着,闭包可以长期保存它所需要的变量,即使这些变量在函数外部已经不存在了。

所以关于判断是否为闭包的条件:

(1)存在于嵌套关系的函数中。

(2)嵌套的内部函数引用了外部函数的变量。

(3)嵌套的外部函数会将内部函数名作为返回值返回。

栗子:

# 定义一个外层函数 outer_num,它接受一个参数 x
def outer_num(x):
    # 定义一个内层函数 inner_num,它接受一个参数 y
    def inner_num(y):
        return x + y
    return inner_num  # 外层函数返回内层函数对象,不立即执行

answer = outer_num(5)
# 调用外层函数 outer_num,并传入参数 5
# 这时,外层函数的参数 x 被赋值为 5,并创建了一个闭包
# 闭包中包含了内层函数 inner_num 和其词法作用域中的变量 x
print(answer(10))

当外层函载的参数x被赋值为5的时候,就算创建完了一个简单的闭包。

最后一句中,内层函数的参数y被赋值为10的时候,内层函数就开始执行,并打印出结果。

二、装饰器

装饰器(Decorator)本质也是python的一种函数,用于修改或增强函数或类的行为。装饰器通过在不修改原始函数代码的情况下,给函数添加新的功能。

装饰器的工作原理是将一个函数作为参数传递给另一个函数,然后返回一个新的函数,这个新的函数在执行时会调用原始函数,并在原始函数的基础上添加额外的行为。

此外、在Python 中,装饰器的语法是以@开头。下面以一个简单的例子来说明下装饰器。

1.通过_不带参数的装饰器_用于运算

    def num(func):
        def inner():  # 定义一个内部函数返回给test函数
            num1 = int(input("请输入第一个因数:"))
            num2 = int(input("请输入第二个因数:"))
            result = num1 * num2  # 计算乘积
            func(result)  # 调用函数并传入计算结果
        return inner  # 返回内部函数

    @num  # 使用装饰器num装饰test函数
    def test(result):  # test函数接收一个参数result
        print('计算结果为:{}'.format(result))  # 把接受结果格式化

    test()  # 调用装饰后的函数,先执行num1和num2的输入,再执行test函数

 打印结果:

2.通过_带参数的装饰器_区分成绩

对带参数的装饰器可理解为“加强装饰”,就是除了调用的函数带上参数,定义的内部函数也要都要带上参数。

def subject(func):
    def mark(a, b, c):  # 如果传入多个参数,就使用不定长参数*args
        func(a, b, c)
    return mark

@subject
def num(a, b, c):
    print("语文:{a}  数学:{b}  英语:{c}".format(a=a, b=b, c=c))
   
num(66, 77, 88)

上面定义的mark()函数内部的执行语句func(),也要带上参数

 

3.通过_多个装饰器_登录应用

多个装饰器可以应用在同一个函数,调用的顺序是自上而下。

def user(buy):
    
    def buyer():

        account = input("请输入账号:")
        if account == 'x':
            buy()
        else:
            print("账户名错误")

    return buyer


def key(buy):
    def buyer():

        password = input("请输入密码:")
        if password == '12345':
            buy()
        else:
            print("密码错误")

    return buyer


@user
@key
def buy():
    print("欢迎来到12306购票")
buy()

(敲黑板)这里的装饰器的应用顺序是:

1.最先应用 @key 装饰器,它返回一个闭包函数。

2.然后应用 @user 装饰器,它返回另一个闭包函数,该函数内部调用 @key 装饰器返回的函数。

所以,当buy()函数被调用时,实际上是这样的调用情况:

user (buyer) ——>  key(buy)

与写闭包的顺序没半毛签关系

调用结果

4.通过_装饰器带返回值函数_判断质数

主要是中间要注意返回传入函数内部调用的参数

 

三、关于序列的常见内置函数

1、map函数

对可迭代对象中的每个元素所应用函数,并返回一个新的迭代器。

map函数语法如下:

map( function,  iterable , ...)

在上述定义中,第一个参数 function 表示的是一个函数名,第二个参数 iterable 可以是序列或支持迭代的容器。当调用 map 函数时,iterable 中的每个元素都会调用function 函数,所有元素调用 function 函数返回的结果会保存到一个迭代的对象中。

栗子:

# lambda函数能接受任何数量参数,这里接受a,b两个,但是返回一个表达式,这里是b*c一种
a = map(lambda b, c: b*c, [1, 2], [4, 5])
# b*c的结果返回给map函数作为参数

print(list(a))  # 然后同过list(a)转成列表形式 打印

这里map 函数中传入的 function 函数带有两个参数:b,c。那么 map 函数需要传递两个序列。 

2、zip函数

在Python中 ,zip()函数用于将两个或多个可迭代对象合并成一个元组的迭代器。zip()函数可以接受任意数量的可迭代对象作为参数,并返回一个元组的迭代器,其中每个元组包含输入可迭代对象中相应位置的元素。(蹩脚的理解:想象多个文件(列表)通过zip压缩到一个压缩包(迭代器)中)

zip函数语法如下:

zip(iterables...)

栗子:

# 创建两个列表
list1 = [1, 2, 3]
list2 = ['  a', 'b', 'c']

# 使用 zip 函数将两个列表合并
combined = zip(list1, list2)

# 打印合并后的元组的列表形式
print(list(combined))

 

3、filter函数

在python中,filter函数会对指定序列执行过滤操作,就是从指定序列中筛选符合条件的元素。filter函数语法如下:

filter ( function,  iterable )

上述语法中看出,filter函数接受两个参数:一个函数和一个序列。函数function用于测试序列中的每个元素是否满足条件,返回值可以为 True或False或None。序列iterable可以是任何序列,如列表、元组、字符串,或者任何可迭代对象,如:生成器表达式。

栗子:

# % 取余数的运算,让它恒等于0(==0),就是筛选处能被整除的数
# 反之不写==0,就是筛选会有余数的数,即:筛选出不能被整除的数

divide = lambda x: x % 4 == 0  # 能被4整除的数

result = filter(divide, [4, 8, 9])

print(list(result))

 

P.s.

周末愉快!加油!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值