语言基础之:装饰器

1 定义

本质是函数,用于装饰其他函数,为其他函数添加附加功能。

1.1 原则

  1. 不能修改被装饰函数的源代码
  2. 不能修改被装饰函数的调用方式

1.2 高阶函数+嵌套函数+闭包==>装饰器

  1. 函数即"变量"
  2. 高阶函数
    把一个函数名当作实参传给另外一个函数(在不修改被装饰函数源代码的情况下为其添加功能)
    ** 返回值中包含函数名(不修改函数的调用方式)
  3. 嵌套函数
# 函数嵌套
def func1():
    def func2()
# 函数调用
def func1():
    func2()
# 变量作用域:中间调用不能缺
def level_1():
    x = 1
    def level_2():
        x = 2
        def level_3():
            x = 3
            print(x)
        level_3()
    level_2()
level_1()
  1. 闭包
    如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是 closure
def timer(func):
    def decorater(*args, **kwargs):
        func(*args, **kwargs)
    return decorater

2 参数与装饰器

2.1 函数存在固定参数

# 函数存在固定参数
def decorater(func):
    def wrapper(name):
        print('updating。。。')
        func(name)
    return wrapper


@decorater
def test(name):
    print('hello world!\n by--{}'.format(name))


test('carey')

2.2 无参装饰器

# 函数无参数
def decorater(func):
    def wrapper():
        print('updating。。。')
        func()
    return wrapper


@decorater
def test():
    print('hello world!')


test()

2.3 有参装饰器

import time

def timer(timer):
    def decorater(func):
        def wrapper(*args):
            if timer == 3:
                print('updating。。。')
                func(*args)
            else:
                start_time = time.time()
                time.sleep(3)
                func(*args)
                end_time = time.time()
                print('end_time - start_time = {}'.format(end_time-start_time))
        return wrapper
    return decorater


@timer(timer=2)
def test(*args):
    print('hello world!%s' % args)


test('carey')

3 实例

#!/usr/bin/env python
# -*- coding:UTF-8 -*-
# Author: Fan Carey
# Version 1.0
# Created time: 
# Description:模拟用户登陆


user, passwd = 'carey', 'passwd'


def auth(auth_type):
    def auth_mode(func):
        def decorater(*args, **kwargs):
            username = input('Username:').strip()
            password = input('Password:').strip()
            if auth_type == 'local':
                if user == username and passwd == password:
                    print('\033[32;1mSuccess!\033[0m')
                    result = func(*args, **kwargs)
                    return result
                else:
                    exit('\033[31;1mInvalid username or password!\033[0m')
            elif auth_type == 'ldap':
                print('ldap auth!')
        return decorater
    return auth_mode


@auth(auth_type='local')  # index = auth_mode(index)
def index():
    print('welcome to index page')
    return 'from index'


@auth(auth_type='ldap')
def home():
    print('welcome to home page')
    return 'from home'


home()

posted @ 2020-06-13 10:39  f_carey  阅读(10)  评论(0编辑  收藏  举报  来源