Python装饰器

本节给大家总结一下装饰器

# 在不更改原功能函数内部代码,并且不改变调用方法的情况下为原函数增加新的功能


def login(index):
    def fun():
        user_name = 'python'
        pw = '123456'
        user = input('请输入帐号')
        password = input('请输入密码')
        if user == user_name and password == pw:
            index()  # 调用传入的函数 也就是调用传入的index 这个是个变量跟调用的函数名无关可以随意更改
        else:
            print('帐号或者密码错误')

    return fun


@login  # @login : 语法糖 --> index = login(index) 会把index 当作一个参数传入到login()函数中 去执行login函数
def index():
    print('这个是首页')


index()


# index = login()
#
# index()


# 带参数的装饰器
def add(func):
    def fun(a, b):
        print('相乘:', a * b)
        func(a, b)

    return fun


# add_num = add(add_num)  在fun函数中需要传参 a, b 先调用fun 然后通过fun 再调用func func()也就是add_num add_num需要两个参数
# 所以给他传入, 因为调用add_num 调用了add函数然后调用了fun函数,我们给add_num传入了两个参数 此时需要给fun函数增加两个参数来接受
# 给add_num 传入的参数, 然后调用了 func()函数 因为func函数也就是传入的add_num函数,add_num函数传入两个参数,也需要在这里给func()
# 函数也增加两个参数来调用add_num 函数
@add
def add_num(a, b):
    print('相加:', a + b)


add_num(1, 2)


# 装饰有参数的函数和没有参数的函数

def add_1(func):
    def fun(*args, **kwargs):
        print('调用装饰器')
        # func(*args, *kwargs)
        return func(*args, *kwargs)

    return fun


@add_1
def index_1():
    print('第二个首页')


@add_1
def add_num_1(a, b):
    print('相加:', a + b)


index_1()
print('-----------------------')
add_num_1(1, 2)


# 装饰器装饰类 类调用装饰器必须在装饰器里面写return 函数不一定要写 不写的话没有对象返回
@add_1  # MyClass = add_1(MyClass)
class MyClass:
    def __init__(self):
        print('这是类')


m = MyClass()
print('m的值是', m)  # m是一个对象
——————————————————————————————————————————————————————————————————————————————————————————————————
import time


def count_time(func):
    def time_1():
        start_time = time.time()
        func()
        end_time = time.time()
        print('运行时间是{:.5f}'.format(end_time - start_time))

    return time_1


def game(func):
    def t():
        for i in range(1, 4):
            a = input('猜年龄:')
            if int(a) == 18:
                print('猜对了')
                break
            else:
                print('本轮游戏结束,你猜错了')
        func()

    return t


# 多个装饰器装饰同一个函数
@game
@count_time
def add():
    time.sleep(5)
    print('这个是需要被装饰的函数')


add()


# 内置装饰器
class MY(object):
    @classmethod  # 被classmethod装饰之后,该方法就是一个类方法
    def add_2(cls):  # cls代表的是类本身 self代表的是实例本身 cls类可以调用 self无法用类调用
        print('add')

    @staticmethod  # 静态方法 实例和类都可以调用
    def stat():
        print('这个是静态方法')

    @property  # 用来装饰只读属性的方法
    def read_attr(self):
        print('1')
        a = 1
        return a


t = MY()
t.read_attr  # 可以不用加()就可以调用
# 通过类来实现装饰器 __call__
import time
time class Tow(object): def __init__(self, fun): self.__fun = fun # 在这初始化函数,使call可以接收到外部传入的函数
def __call__(self,
*args, **kwargs): start_time = time.time() self.__fun(*args, *kwargs) print('调用装饰器') end_time = time.time() a = end_time - start_time print(a) @Tow def func(): time.sleep(3) print('函数') func() # 单例模式装饰器 def single(cls): instance = {} def fun(*args, **kwargs): if cls in instance: return instance[cls] else: instance['cls'] = cls(*args, **kwargs) return instance['cls'] return fun @single class One(): pass @single class Tow(): pass

 

posted @ 2020-03-23 23:12  白加黑呀  阅读(350)  评论(0编辑  收藏  举报