python闭包、装饰器、类方法

一、 闭包

定义:外部函数中定义一个内部函数,内部函数引用外部函数中的变量,外部函数的返回值是内部函数。

闭包与装饰器区别

  • 闭包传递的是变量,而装饰器传递的是函数;

  • 除此之外没有任何区别,或者说装饰器是闭包的一种,它只是传递函数的闭包。

闭包的简单示例:

def out(i):
    def inner(j):
        return i*j
    return inner

#调用闭包
res = out(2)     # i=2
print(res(10))   # j=10

# 输出20

当内函数中需要修改外函数的值时:
用nonlocal 关键字声明一个变量,表示这个变量不是局部变量空间的变量,需要向上一层变量空间找这个变量。

image.png

注意:使用闭包的过程中,一旦外函数被调用一次返回了内函数的引用,虽然每次调用内函数,是开启一个函数执行过后消亡,但是闭包变量实际上只有一份,每次开启内函数都在使用同一份闭包变量。

以下代码中的x即为第一次调用后修改过的x:
在这里插入图片描述
在闭包中引用循环变量:
在这里插入图片描述

二、装饰器

装饰器本质上是一个可调用的对象,一般由函数、类来实现,主要用途是包装另一个函数或类。

好处:在不用更改原函数的代码前提下给函数增加新的功能。
在这里插入图片描述

多个装饰器时:
在这里插入图片描述

装饰器接受参数:
在这里插入图片描述
类装饰器也相当于一种函数,它接受类作为输入并返回类作为输出:
在这里插入图片描述

三、带参数的装饰器

(1)带固定参数的装饰器:

在这里插入图片描述
(2)带不定参数的装饰器:

在这里插入图片描述
(3)装饰器带参数:

在这里插入图片描述

四、 装饰器的使用场景

(1)时间计时器

def timer(func):
    def wrapper(*args,**kwargs):
        t1 = time.time()
        func(*args,**kwargs)
        t2 = time.time()
        cost_time = t2 -t1
        print("花费时间:{}秒".format(cost_time))
    return wrapper

(2)日志打印器

def logger(func):
    def wrapper(*args,**kwargs):
        print("准备开始计算:{}函数".format(func.__name__))
        func(*args,**kwargs)
        print("计算完成")

(3)@staticmethod 和 @classmethod 的 区别 和 使用场景:
在这里插入图片描述
@classmethod装饰的类方法里面,会传一个cls参数,代表本类,这样就能够避免手写类名的硬编码。

使用场景:

在定义类的时候,假如不需要用到与类相关的属性或方法时,就用静态方法@staticmethod;

假如需要用到与类相关的属性或方法,然后又想表明这个方法是整个类通用的,而不是对象特异的,就可以使用类方法@classmethod。

五、三个内置装饰器:staticmethod、classmethod、property

1、staticmethod
2、classmethod 类装饰器
3、property类静态属性装饰器。 把类的方法伪装成属性

1和2都可以用 类名.方法名 进行直接调用,而不用创建实例对象;
两者区别

  • classmethod是需要cls参数的,cls和self一样,代表类本身,但是 cls不能调用实例对象的属性,即不能调用def __ init __ 下面的属性。可以通过 cls.类属性 或 cls.类方法 来调用类的属性和方法。
  • staticmethod不需要self和cls参数,它注重的是类的静态变量,跟类的实例化对象没有关系,所以它 也不能调用类实例化对象的属性,即def __ init __ 下面的属性,而且只能通过 类名.类属性,类名.类方法 来调用类的属性和方法。

举例

#classmethod, staticmethod
class my_class():

    __pwd = 123456

    def __init__(self):
        self.name = '老六'

    @classmethod
    def func1(cls):
        #不能调用实例对象的属性,可以通过cls调用类的属性
        print("this is func1")
        print(cls.__pwd)

    @staticmethod
    def func2():
        #不能调用实例对象的属性,只能调用类的属性
        print("this is func2")
        print(my_class.__pwd)

    def func3(self):
        #可以调用实例对象的属性,也可以调用类的属性
        print("this is func3")
        print(self.__pwd)
        print(self.name)

#func1有classmethod装饰,func2有staticmethod,func3没有进行任何装饰
my_class.func1()
my_class.func2()
#需要创建实例对象才能调用func3
my_class().func3()

>>>
this is func1
123456
this is func2
123456
this is func3
123456
老六



1、staticmethod:

将类中的方法装饰为静态方法,即类不需要创建实例的情况下,可以通过类名直接引用。到达将函数功能与实例解绑的效果。
在这里插入图片描述

2、classmethod 类方法

类方法的第一个参数是一个类,是将类本身作为操作的方法。类方法被哪个类调用,就传入哪个类作为第一个参数进行操作。参数写slef或cls都行。。可以不用创建实例对象直接进行类名.类方法调用(见第二个举例)。
在这里插入图片描述
不需要self参数:但第一个参数需要是表示自身类的 cls 参数
在这里插入图片描述

3、property:

property一般有两个作用,如下:

  • 作为装饰器,@property 将类的方法转为只读的类属性。
    例如:它把sayHello方法变成了一个属性,使用的是cls.sayHello而不是cls.sayHello()。
  • property 重新实现一个属性的 getter 和 setter 方法。

适应场景:
1.只读不可修改的属性。只需要实现@property
2.输入对setter进行判断。
3.需要实时地计算属性值。
在这里插入图片描述
*args和**kwargs区别:
*args代表任何多个无名参数,返回的是元组;**kwargs表示关键字参数,所有传入的key=value,返回字典;

下面@property 重新实现一个私有属性的 getter 和 setter 方法。

class E():
    __name = '张三'

    def __init__(self):
        self.__age = 23
        self.__luange = 'python'

    def __method(self):
        print("我叫{},今年{}岁,我喜欢{}。".format(self.__name, self.__age, self.__luange))

    @property
    def name(self):
        return self.__name
        
    @name.setter
    def name(self, name):
        self.__name = name

if __name__ == '__main__':
    e = E()
    #访问
    print(e.name)
    #修改
    print("修改前:", e.name)
    e.name = '隔壁老王'
    print("修改后:", e.name)

>>>
张三
修改前: 张三
修改后: 隔壁老王

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
闭包装饰器是一种特殊的装饰器,它使用闭包的概念来实现。闭包是指一个函数可以访问并操作其外部函数中定义的变量。在Python中,闭包装饰器可以用于给函数添加额外的功能,同时保持函数的原始定义不变。 引用中的示例展示了装饰器传参的形式。在这个例子中,outer函数是一个装饰器,它将inner函数作为子函数返回,并在inner函数中添加了额外的功能。通过使用@outer装饰器语法,我们可以在add函数上应用outer装饰器,从而在调用add函数时执行装饰器中的代码。 引用中的示例展示了多层装饰器的使用。在这个例子中,outer1和outer2函数分别是两个装饰器,他们都返回一个inner函数。通过使用@outer1和@outer2装饰器语法,我们可以在outers函数上应用这两个装饰器,并在调用outers函数时按照装饰器的定义顺序执行相关的代码。 引用提供了关于Python闭包装饰器的使用方法的总结。这篇文章通过示例代码详细介绍了闭包装饰器的使用,对于学习和工作有一定的参考价值。 引用中的示例展示了装饰器的形式。在这个例子中,outer函数是一个装饰器,它将inner函数作为子函数返回,并在inner函数中添加了额外的功能。通过使用@outer装饰器语法,我们可以在add函数上应用outer装饰器,从而在调用add函数时执行装饰器中的代码。 综上所述,Python闭包装饰器是一种利用闭包概念实现的特殊装饰器,可以用于给函数添加额外的功能。这种装饰器可以通过装饰器传参的形式、多层装饰器的形式或普通的装饰器形式来实现。<span class="em">1</span><span class="em">2</span><span class="em">3</span><span class="em">4</span>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值