Python笔记_21_装饰器

装饰器:

  • 装饰器 : 在不改变原有代码的情况下,为该原函数扩展新功能
  • 特征 : 返回新函数,替换旧函数
  • 语法 : @(语法糖)
装饰器原型
def kuozhan(func):
    def newfunc():
        print("厕所前,屁滚尿流")
        func()
        print("厕所后,站不起来")
    return newfunc


def func():
    print("我是个屌丝")


# 手动的 把新函数 赋值给 旧函数
func = kuozhan(func)  # res = newfunc
func()  # newfunc()
装饰器@
def kuozhan(func):
    def newfunc():
        print("厕所前,风流倜傥")
        func()
        print("厕所后,面黄肌瘦")
    return newfunc


@kuozhan
def func():
    print("我是一个高富川")


'''
第一步: 先把下面的func当成参数传递给kuozhan
第二部:把返回的新函数重新赋值给func
* 谁跟在@ 这个装饰器的下面,就会自动把谁当成参数传递
func = kuozhan(func)
'''
func()
互相嵌套的装饰器函数
def kuozhan1(func):
    def newfunc():
        print("厕所前,蓬头垢面1")
        func()
        print("厕所后,精神抖擞2")
    return newfunc


def kuozhan2(func):
    def newfunc():
        print("吃饭前,洗洗手3")
        func()
        print("吃饭后,洗洗脚4")
    return newfunc


@kuozhan2
@kuozhan1
def func():
    print("我是一个白富美5")


func()  # 3 1 5 2 4
带有参数的装饰器
  • 原函数在扩展之前是几个参数,那么扩展之后也相应有几个参数
def kuozhan(func):
    def newfunc(who, where):
        print("厕所前,干净整洁")
        func(who, where)
        print("厕所后,臭气熏天")
    return newfunc


@kuozhan
def func(who, where):
    print('{}在{}解手'.format(who, where))


func("马军强", "鸟窝")
带有参数返回值的装饰器
  • 通过装饰器改造之后,原函数返回什么,新函数返回什么
def kuozhan(func):
    def newfunc(*args, **kwargs):
        print("厕所前,萎靡不振")
        # "电影院","游泳池",jzn="15克",ys="15碗",hw="15斤",sc="15吨"
        res = func(*args, **kwargs)
        print("厕所后,兽性大发")
        return res

    return newfunc


@kuozhan
def func(*args, **kwargs):
    print(args)
    for i in args:
        print("茅厕的地点在:", i)
    # print(kwargs)
    dic = {'jzn': "境泽年", "ys": "易思", "hw": "黄文", "sc": "舒畅"}


    lst = ["{} 留下了黄金 {}".format(dic[k], v)
           for k, v in kwargs.items() if k in dic]
    return lst


res = func("电影院", "游泳池", jzn="15克", ys="15碗", hw="15斤", sc="15吨")
print("<112233>")
print(res)

用类装饰器修饰原函数
class MyClass():

    def __call__(self, func):
        return self.kuozhan2(func)

    def kuozhan1(func):
        def newfunc():
            print("厕所前,饥肠辘辘")
            func()
            print("厕所后,酒足饭煲")
        return newfunc

    def kuozhan2(self, func):
        def newfunc():
            print("厕所前,茶饭不思")
            func()
            print("厕所后,满口雌黄")
        return newfunc


# 方法一
@MyClass.kuozhan1
def func():
	print("厕所进行时... ... ")
func()


# 方法二
@MyClass()  # @obj => obj(func)
def func():
    print("厕所进行时... ... ")


func()

带有参数的函数装饰器
def outer(num):
    def kuozhan(func):
        def newfunc1(self):
            print("厕所前,老实巴交")
            func(self)
            print("厕所后,长牙舞爪")

        def newfunc2(self):
            print("厕所前,衣冠楚楚")
            func(self)
            print("厕所前,衣冠禽兽")

        if num == 1:
            return newfunc1
        elif num == 2:
            return newfunc2
        elif num == 3:
            return "今天天气好晴朗哦"
    return kuozhan


class MyClass():

    @outer(1)
    def func1(self):
        print("向前一小步")

    @outer(2)
    def func2(self):
        print("文明一大步")

    @outer(3)
    def func3(self):
        print("来也冲冲,去也冲冲")


print("<===>")
obj = MyClass()
obj.func1()
print("<===>")
obj.func2()
print("<===>")
print(obj.func3)

'''
outer(1) => 返回 kuozhan 函数
@kuozhan
func1

@符号开始发挥作用
把func1当成参数进行传递,传给kuozhan中的func进行接收
根据num 这个值进行判断 , 返回newfunc1
obj.func1 = newfunc1
obj.func1() <===> newfunc1()


@outer(2) => 返回 kuozhan 函数
@kuozhan
func3
@符号开始发挥作用
把func3当成参数进行传递,传给kuozhan中的func进行接收
obj.func3 = "今天天气好晴朗哦"
print(该值) [因为函数名可以作为变量使用.]
'''

带有参数的类装饰器

要求:如果传递的参数是1,我就为该类,添加成员属性和方法
   如果传递的参数是2,我就把该类当中的run方法变成属性

class Kuozhan():
    ad = "贵族茅厕,欢迎您来,欢迎您在来"

    def __init__(self, num):
        self.num = num

    def __call__(self, cls):
        if self.num == 1:
            return self.kuozhan1(cls)  # newfunc 返回

        elif self.num == 2:
            return self.kuozhan2(cls)

    def money(self):
        print("贵族茅厕收费标准,每小时10元,包月1400")

    def kuozhan1(self, cls):
        def newfunc():
            # 添加成员属性
            cls.ad = Kuozhan.ad
            # 添加成员方法
            cls.money = Kuozhan.money
            return cls()

        return newfunc

    def kuozhan2(self, cls):
        def newfunc():
            # 先来判断run方法是否在cls当中
            if "run" in cls.__dict__:
                # 调用一个类中得run方法拿到返回值"亢龙有悔"
                res = cls.run()
                # 成员属性run 从方法变成属性,值替换了
                cls.run = res  # 把"亢龙有悔"进行替换赋值给run成员属性
            return cls()
        return newfunc


@Kuozhan(1)  # @obj => obj(MyClass)
class MyClass():
    def run():
        return "亢龙有悔"


obj = MyClass()
print(obj.ad)
obj.money()
"""
Kuozhan(1) => obj  自动触发init方法,存储num =>self.num = num
@obj
@符发挥作用把MyClass当成一个参数传递给obj => obj(MyClass)
触发__call__魔术方法,最后将newfunc进行返回
MyClass = newfunc  以前是类 现在是函数
obj = MyClass() <===>  newfunc()
obj = cls() # cls() 是一个对象 是以前MyClass 这个类的对象
"""


@Kuozhan(2)
class MyClass():
    def run():
        return "亢龙有悔"


obj = MyClass()
print(obj.run)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值