• 装饰器


    def outer(func):
        def inner():
            print('before')
            func()
            print('after')
        return inner
    
    @outer
    def f1():
        print('f1')

    功能:

    1.自动执行outer()函数,并把outer函数下面的函数名作为参数传递给outer函数

    2.将outer函数的返回值重新赋值给f1

    以上代码执行过后:

    1.f1不在指向原来的f1函数,而是执行inner函数

    2.func执指向原来的f1函数

    也就是说函数被装饰器装饰之后,被装饰的函数名引用指向装饰器函数的内层函数即inner()

    • 一.装饰器流程之返回值
    def outer(func):
        def inner():
            print('before')
            ret = func() # 接收原来f1函数的返回值
            print('after')
            return ret # 将函数之返回
        return inner
    
    @outer
    def f1():
        return 'f1'
    
    f1()
    • 二.装饰器流程之参数
    def outer(func):
        def inner(a,b): # 加参数
            print('before')
            ret = func(a,b)  # 加参数
            print('after')
            return ret  # 将函数之返回
    
        return inner
    
    
    @outer
    def f1(a, b):
        return a + b
    
    f1(1,2)
    • 三.装饰器流程之多参数
    def outer(func):
        def inner(*args,**kwargs): # 加参数
            print('before')
            ret = func(*args,**kwargs)  # 加参数
            print('after')
            return ret  # 将函数之返回
    
        return inner
    
    
    @outer
    def f1(a, b):
        return a + b
    
    f1(1,2)
    • 装饰器带参数
    """
    装饰器不带参数时,直接返回的是一个函数 inner
    装饰器带参数之后,第一个外层函数接收参数,并返回一个装饰器  outer
    """
    
    
    def outer_args(args):  # args 接收装饰器的参数
        def outer(func):   # func 接收需要装饰的函数
            #  扩展函数功能
            def inner_admin_user():
                print('before', 'admin')
                result = func()
                print('after', 'admin')
                return result
    
            #  扩展函数功能
            def inner_commons_user():
                print('before', 'commons')
                result = func()
                print('after', 'commons')
                return result
    
            # 根据装饰器的参数返回不同的装饰之后的函数
            if args == 'admin':
                return inner_admin_user
            else:
                return inner_commons_user
    
        # 返回装饰器
        return outer
    
    
    @outer_args('admin')
    def f1():
        print('F1')
        return 'f1'
    ret = f1()
    print(ret)
    
    
    @outer_args('select')
    def f2():
        print('F2')
        return 'f2'
    
    res = f2()
    print(res)
    • 使用类做装饰器
    """
    使用类作为装饰器:
        1. 需要定义__call__(self, func) 用以接收被装饰的函数名参数
        2. 在类中在定义一个方法,扩展功能
        3. self.func = func  把被装饰的函数名封装到对象中
        4.  return self.inner  把返回的函数封装到对象中
        5. 如果装饰器需要传入参数,类中需定义__init__(self, args) 用以接收参数
        6. 使用类中装饰器是 @Decorator1() 有个括号
    
    """
    
    
    class Decorator1(object):  # 使用类作为装饰器 且装饰器不带参数
    
        # 一个用于接收基本函数装饰器
        def __call__(self, func):
            print(func)
            self.func = func  # 把被装饰的函数名封装到对象中
            return self.inner  # 把返回的函数封装到对象中
    
        # 一个用于扩展功能
        def inner(self):
            print('before')
            ret = self.func()
            print('after')
            return ret
    
    
    class Decorator2(object):  # 装饰器带参数
    
        def __init__(self, args):
            self.args = args
    
        def __call__(self, func):
            self.func = func
    
            if self.args == 'admin':
                return self.inner_admin_user
            else:
                return self.inner_commons_user
    
        def inner_admin_user(self):
            print('before', 'admin')
            result = self.func()
            print('after', 'admin')
            return result
    
        def inner_commons_user(self):
    
            print('before', 'commons')
            result = self.func()
            print('after', 'commons')
            return result
    
    
    @ Decorator1()
    def f1():
        print('f1')
    f1()
    
    
    @Decorator2('admin')
    def f2():
        print('f1')
    f2()
    
    
    @Decorator2('commons')
    def f2():
        print('f1')
    f2()
    • 为类添加装饰器
    """
    为类添加装饰器:
        1. outer(cls)  cls为类名
        2. 内层函数需返回对象
        3.为类加装饰器用处在什么地方呢,参数为cls 除了创建对象, 调用类中的方法,还有什么呢
    """
    
    
    def decorator(args):
        def outer(cls):
            def inner_morning():
                print('早上开始创建对象..')
                obj = cls()
                print('始创建对象结束..')
                return obj  # 需返回对象
    
            def inner_noon():
                print('中午开始创建对象..')
                obj = cls()
                print('始创建对象结束..')
                return obj
            if args == '12':
                return inner_morning
            else:
                return inner_noon
        return outer
    
    
    @decorator('13')
    class Work(object):
        pass
    aa = Work()
    

      

    • 四.装饰器流程练习
    UserInfo = {'name': 'alex', 'age': 18, 'sex': '男'}
    Login_flag = False
    Login_type = None
    # 用户登陆查询用户信息,查看信息之前先登陆,进行后台管理,必须是管理员


    def check_login(func):
    def inner(*args,**kwargs):
    if Login_flag is True:
    func()
    else:
    print('请先登陆...')
    return inner


    def check_type(func):
    def inner(*args,**kwargs):
    if Login_type == 1:
    func()
    else:
    print('无权限')
    return inner


    def login(name, pwd):
    global Login_flag, Login_type
    if name == 'admin':
    Login_flag = True
    Login_type = 1
    elif name == 'alex' and pwd == '123':
    Login_flag = True
    else:
    pass


    @check_login
    def select():
    for li in UserInfo.keys():
    print(UserInfo[li])


    @check_login
    @check_type
    def admin():
    print('后台管理')

    inp = input('1:登陆 2:查看用户,3:后台管理 >>>')
    name = input('UserName:>>>')
    pwd = input('PassWord:>>>')
    if inp == '1':
    login(name, pwd)
    elif inp == '2':
    select()
    elif inp == '3':
    # login(name, pwd)
    login(name, pwd)
    admin()
  • 相关阅读:
    POJ1045 Bode Plot
    POJ1044 Date bugs
    POJ1043 What's In A Name?
    POJ1042 Gone Fishing
    POJ1041 John's trip
    POJ1040 Transportation
    POJ1039 Pipe
    background-size属性
    一些CSS的备忘
    only-child选择器
  • 原文地址:https://www.cnblogs.com/liyqiang/p/6285850.html
Copyright © 2020-2023  润新知