首页 > 编程语言 > python 装饰器

python 装饰器

时间:2023-05-30 16:14:53浏览次数:40  
标签:index 函数 python res time print 装饰 def

一、核心思想

不改变被装饰对象内部代码原有调用方式的基础之上在添加额外的功能

二、装饰器的实现过程

根据实际需要,一步一步满足需求,完成对装饰器的理解

1、简易版本

给index函数添加统计执行时间的功能

import time

def index():
    time.sleep(3)
    print('from index')

def home():
    time.sleep(2)
    print('from home')

def func():
    time.sleep(2)
    print('from home')

def outer(func): # 外层函数
    def get_time(): # 内层函数
 
        # 1. 在函数执行之前打一个时间点
        start_time = time.time()
        
        func()  # index() 

        # 2. 在函数执行完毕之后在打一个时间点
        end_time = time.time()

        # 3. 两个时间的差值就是函数的实际执行时间
        print("函数执行了:%s秒" % (end_time - start_time))

    return get_time  # 返回内层函数


# 利用闭包的形式来传参
# res = outer(index)  # res:get_time的内存地址
# res()  # get_time()

home = outer(home)
home()

2、解决参数的问题

当执行不同的函数,计算不同函数的执行时间,有的函数有参数,有的函数没参数

def index(name, username):
    time.sleep(3)
    print('from index')

def home(name):
    time.sleep(2)
    print('from home', name)

def outer(func):
    def get_time(*args, **kwargs):
        
        # 1. 在函数执行之前打一个时间点
        start_time = time.time()
        
        func(*args, **kwargs)  # 原有函数
        
        # 2. 在函数执行完毕之后在打一个时间点
        end_time = time.time()

        # 3. 两个时间的差值就是函数的实际执行时间
        print("函数执行了:%s秒" % (end_time - start_time))

    return get_time
index = outer(index)
index('tony', username='tank')            

3、解决返回值问题

def home(name):
    time.sleep(2)
    print('from home', name)

def index():
    time.sleep(3)
    print('from index')
    return 'from index'

def outer(func):
    # func = index
    def get_time(*args, **kwargs):
        # func:index
        # 1. 在函数执行之前打一个时间点
        start_time = time.time()
        res=func(*args, **kwargs)  # index()  func('tony')
        # 2. 在函数执行完毕之后在打一个时间点
        end_time = time.time()

        # 3. 两个时间的差值就是函数的实际执行时间
        print("函数执行了:%s秒" % (end_time - start_time))
        return res
    return get_time
index = outer(index)
res=index()
print(res)

4、装饰器模板

def outer(func):
    def inner(*args, **kwargs):
        print('这个是函数执行之前可以添加的功能')
        res = func(*args, **kwargs)
        print('这个是函数执行之后可以添加的功能')
        return res

    return inner


def index():
    print('from index')


index = outer(index)
index()

5、装饰器的模板

def outer(func):
    def inner(*args, **kwargs):
        print('这个是函数执行之前可以添加的功能')
        res = func(*args, **kwargs)
        print('这个是函数执行之后可以添加的功能')
        return res

    return inner


def index():
    print('from index')


index = outer(index)
index()

6、装饰器的语法糖

'''
只要有一个函数认证成功,其他函数就不用验证了
需要一个变量来保存登录用户登录成功的标志
'''
is_login = {'is_login': False}

# 使用闭包函数实现装饰器
def login(func):
    def auth(*args, **kwargs):  # 可变长参数:接受多余的位置参数和关键字参数,没有参数则接受为空,不报错,正常执行,满足有参和无参两种使用场景
        if is_login.get('is_login'):  # 字典 get 方法取值为 False,表示 if False:条件不成立时不执行
            # 前一个函数执行完,is_login赋值为 True,执行下面的代码
            res = func(*args, **kwargs)  # 调用函数,函数的返回值赋值给 res,再返回 res 给到 auth 函数
            return res
            # 简易登录认证系统
        username = input("Enter username: ").strip()
        passwd = input("Enter password: ").strip()
        # 验证用户名密码
        if username == 'jingzhiz' and passwd == '123':
            print('登录成功!')  # 函数执行前的操作
            res = func(*args, **kwargs)  # 要执行的函数
            is_login['is_login'] = True
            return res  # 函数执行后的操作
        else:
            print('认证失败!')

    return auth

'''
 语法糖需要定义在装饰器的下方,函数的上方紧贴着
 去掉语法糖可以实现原函数的正常调用
 语法糖格式@+装饰器外层函数名
 @login的理解 
   index=login(),index 只是一个变量名,也可以是res,只是为了满足装饰器思想:不改变原函数的调用方式写成原函数名,打印内存地址于原函数不是一个
   login()会返回 auth 的(函数名)即内存地址,实现 index = auth 即 index()=auth()。
'''
@login
def index(name):
    print('from index', name)
    return '返回值测试'

@login
def home():
    print('from home')

# 装饰器的最终效果:保持函数的原始调用方式的同时,增加新的功能
res = index('jinghiz')
print(res)
home()

 

 

 

 

7、

 

标签:index,函数,python,res,time,print,装饰,def
From: https://www.cnblogs.com/dgp-zjz/p/17443497.html

相关文章

  • python selenium web网站登录缺口图片验证码识别
    deflogin():driver=webdriver.Chrome("browser_driver/chromedriver.exe")driver.get("http://xxxxxx/#/login")driver.maximize_window()sleep(1)driver.find_element(By.CSS_SELECTOR,'[placeholder="请输入手机号&qu......
  • python
    静态方法:需在类成员函数前面加上@staticmethod标记符,以表示下面的成员函数是静态函数。使用静态方法的好处是,不需要定义实例即可使用这个方法。另外,多个实例共享此静态方法。classPerson:grade=1def__init__(self,name):self.name=name......
  • Python excejs 执行js文件的时候 报编码错误的问题
    问题执行js的时候报图中的编码错误,直接执行js文件时能正常编译,在网上未找到关于这个问题的文章头疼了好久最终在各位大佬的帮助下解决了问题,便记录了下来:解决办法:一、修改报错文件subprocess.py中的encoding编码:encoding=None--->encoding='utf-8'二、在引包的时......
  • 【爬虫+数据清洗+可视化】用Python分析“淄博烧烤“的评论数据
    目录一、背景介绍二、爬虫代码2.1展示爬取结果2.2爬虫代码讲解三、可视化代码3.1读取数据3.2数据清洗3.3可视化3.3.1IP属地分析-柱形图3.3.2评论时间分析-折线图3.3.3点赞数分布-箱线图3.3.4评论内容-情感分布饼图3.3.5评论内容-词云图四、技术总结五、演示视频六、完整......
  • python日期和时间
     1、获得当前时间#!/usr/bin/python#-*-coding:UTF-8-*-importtimelocaltime=time.localtime(time.time())print"本地时间为:",localtime2、获得格式化时间可以根据需求选取各种格式,但是最简单的获取可读的时间模式的函数是asctime():#!/usr/bin/pytho......
  • Python 读取图片 转 base64 并生成 JSON
    Python读取图片转base64并生成JSONimportjsonimportbase64img_path=r'D:\OpenSource\PaddlePaddle\PaddleOCR\images\005.jpeg';withopen(img_path,'rb')asfile:image_data1=file.read()image=base64.b64encode(image_data1).de......
  • 【Python】将中文字符写入json文件
    ensure_asciiimportjsondict1={'name':'时间','data':['2023-04-1305:00']},{'name':'雨量mm/h','data':['0.0000']},{'name':'温度℃','data':[&......
  • python爬虫 requests访问http网站之443报错(ssl验证)
    报错信息:urllib3.exceptions.MaxRetryError:HTTPSConnectionPool(host='ssr4.scrape.center',port=443):Maxretriesexceededwithurl:/page/1(CausedbySSLError(SSLCertVerificationError(1,'[SSL:CERTIFICATE_VERIFY_FAILED]certificateverifyfa......
  • 【python】字符串
    字符串startwithstartswith()方法用于检查字符串是否是以指定子字符串开头,如果是则返回True,否则返回False。如果参数beg和end指定值,则在指定范围内检查。语法:str.startswith(substr,beg=0,end=len(string));参数str:检测的字符串。substr:指定的子字符串。beg:可选......
  • Python QQ群数据获取
    code来自于一个神奇的小伙伴:https://www.cnblogs.com/code3importcontextlibimporttimeimportrequestsimportdatetimeimportpandasaspdimportpymysqlimportosimportjsonclassQQSpider:def__init__(self):self.session=requests.Session(......