linux中的加法函数,上下文管理练习(为加法函数计时)
上下文管理(为加法函数计时)
为加法函数计时
使用装饰器显示该函数的执行时长
使用上下文管理显示该函数的执行时长
装饰器实现
import time
import datetime
from functools import wraps
def logger(fn):
@wraps(fn) # wraps(fn)(wrapper)
def wrapper(*args, **kw):
start = datetime.datetime.now()
ret = fn(*args, **kw)
delta = (datetime.datetime.now() - start).total_seconds()
print(delta)
return ret
return wrapper
@logger
def add(x, y):
time.sleep(2)
return x + y
上下文实现
最简单实现
增加__call__用法
import time
import datetime
class TimeIt:
def __init__(self, fn):
self.fn = fn
def __enter__(self):
self.start = datetime.datetime.now()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.delta = (datetime.datetime.now() - self.start).total_seconds()
print(self.delta)
def __call__(self, *args, **kwargs):
ret = self.fn(*args, **kwargs)
return ret
def add(x, y):
""" This is add"""
time.sleep(2)
return x + y
with TimeIt(add) as foo:
print(foo(3,4))
需要增加初始化方法,为下面__call__使用
__enter__方法返回self是为了,有了__call__方法以后,可以这样使用with TimeIt(add) as foo: foo(3,4)
因为有了__call__后,实例变成可调用,而foo就是实例化后的实例
TimeIt(add)是将add函数名作为形参传进去
改成装饰器
import time
import datetime
class TimeIt:
def __init__(self, fn):
self.fn = fn
def __enter__(self):
self.start = datetime.datetime.now()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.delta = (datetime.datetime.now() - self.start).total_seconds()
print(self.delta)
def __call__(self, *args, **kwargs):
print('call')
ret = self.fn(*args, **kwargs)
return ret
@TimeIt # add = TimeIt(add)
def add(x, y):
""" This is add"""
time.sleep(2)
return x + y
# 上下文用法
# with TimeIt(add) as foo:
# print(foo(3,4))
print(add(5,6))
print(add.__doc__)
print(add.__dict__)
print(add.__name__)
装饰器用法很简单,直接在add函数上加个@TimeIt
这是由于@TimeIt等价于add = TimeIt(add),把add函数名作为实参传入到TimeIt类中
就相当于为add函数加了一个类封装的功能或属性
而这个时候,我们发现,用装饰器实现后,直接走的是__call__方法中的语句块,而上下文没有执行(因为没有用with..as语句)
也就是说,要么用with..as语句,要么用装饰器方法,这是两个方法
(用with..as语句执行装饰器方法,这样比较繁琐,重复计算,因题而异)
但是,如何解决文档字符串的问题,怎么把add函数的配置信息也弄过来(看__doc__和__dict__就可以知道)
解决文档字符串问题
方法1
把函数对象的文档字符串赋给类
class TimeIt:
def __init__(self, fn):
self.fn = fn
self.__doc__ = self.fn.__doc__
self.__name__ = self.fn.__name__
self.__dict__ = self.fn.__dict__
方法2
使用functools.wraps函数
最终完整版
import time
import datetime
from functools import wraps
class TimeIt:
"""This is Class"""
def __init__(self, fn):
self.fn = fn
# 把函数对象的文档字符串赋给类
# self.__doc__ = self.fn.__doc__
# self.__name__ = self.fn.__name__
# @wraps = wraps(fn)(wrapper)
wraps(fn)(self) # wraps用法
# def __enter__(self):
# self.start = datetime.datetime.now()
# return self
# def __exit__(self, exc_type, exc_val, exc_tb):
# self.delta = (datetime.datetime.now() - self.start).total_seconds()
# print(self.delta)
def __call__(self, *args, **kwargs):
print('call')
self.start = datetime.datetime.now()
ret = self.fn(*args, **kwargs)
delta = (datetime.datetime.now() - self.start).total_seconds()
print(delta)
return ret
@TimeIt # add = TimeIt(add)
def add(x, y):
""" This is add"""
time.sleep(2)
return x + y
# 上下文用法
# with TimeIt(add) as foo:
# print(foo(3,4))
print(add(5,6))
print(add.__doc__)
print(add.__dict__)
print(add.__name__)
print(type(add))
第15行的用法wraps(fn)(self)是根据这个@wraps = wraps(fn)(wrapper)来的
@wraps是带参装饰器,fn就是带参,wrapper是传入的实参
简单来说,@wraps = wraps(fn)(wrapper)就是把fn的配置信息赋值给wrapper
所以wraps(fn)(self)就是把fn的配置信息赋值给实例(self就是实例化后的实例)
本文来自投稿,不代表Linux运维部落立场,如若转载,请注明出处:http://www.178linux.com/88584
linux中的加法函数,上下文管理练习(为加法函数计时)相关推荐
- python上下文管理关键字_详解 Python 中的 with 与 上下文管理器
with 这个关键字,对于每一学习Python的人,都不会陌生. 操作文本对象的时候,几乎所有的人都会让我们要用 with open ,这就是一个上下文管理的例子.你一定已经相当熟悉了,我就不再废话了 ...
- Linux中用户的简介与管理
女主宣言 众所周知,linux是一个多用户.多任务的操作系统.那么linux是如何区分和认证用户的,系统对每个用户的授权是如何管理的,出现问题时是如何追朔每个用户在系统内的操作记录,这些就涉及到了li ...
- Linux 中的逻辑卷 LVM 管理完整初学者指南
这是 Linux 中 LVM(逻辑卷管理)的完整初学者指南. 在本教程中,您将了解 LVM 的概念.它的组件以及为什么要使用它. 我不会仅限于理论上的解释,我还将展示在 Linux 中创建和管理 LV ...
- Linux中源码包的管理
什么是开放源码,编译程序和可执行文件 开放源码:就是程序代码,写给人类看的程序语言,但机器不认识,所以无法执行: 编译程序:将程序代码转译成为机器看得懂的语言: 可执行文件:经 ...
- linux中的权限管理,Linux中的用户和权限管理
Linux是多用户,多任务操作系统:多用户是指多个用户可以同时使用系统资源,而多任务指同时运行多个进程. 用户是能够获取系统资源的权限的集合,Linux通过用户实现资源分隔. 用户组是具有相同特征用户 ...
- Linux内核学习笔记——Linux中的用户组和权限管理(UID是什么?)
目录 一.背景 进程权限 最小权限原则 二.linux系统安全模型 用户 用户组 用户和组的关系 安全上下文 进程的用户ID 函数setreuid和setregid 函数seteuid和setegid ...
- python实现可以被with上下文管理的类或函数
开始之前先明确一下with机制 1.类包函数__ enter__()和__exit__()函数,即是可以被上下文管理的类 __enter__用来执行with时的方法,__exit__返回对象给with ...
- Linux中用户与组群管理
Linux是一个多用户操作系统,可以多个用户同时使用同一计算机,不同的用户对相同的资源拥有不同的使用权限,将同一类的用户归于一个组群,可以利用组群权限来控制组群成员用户的权限. Linux中用户分为三 ...
- c++ getpid函数_C Linux中的getpid()和getppid()函数
c++ getpid函数 If we are working on the processes, signals related programming using C language in Lin ...
最新文章
- [转]阿里巴巴数据库连接池 druid配置详解
- python二分法递归_python 【递归 及 二分法】
- Redis操作Key
- php上传手机文件到服务器,安卓上传文件至PHP服务器(示例代码)
- angular 渐进_如何创建具有Angular和无头CMS的渐进式Web应用程序
- 人大提出新模型,将Two Stage的Video Paragraph Captioning变成One Stage,性能却没下降...
- SqlServe零碎要点---sqlserver如何使用日期计算,DateTime类型的格式化以及语法格式等等。
- python 帮助教师_花10分钟写一个Python脚本,搞定了初中老师一下午的工作
- js获取地址栏url以及获取url参数
- IDEA——使用JSONObject时报错怎么办?
- MySQL Client/Server Protocol
- 怪物猎人世界pc服务器在哪个文件夹,关于PC怪物猎人世界拆包文件的一些问题...
- python int too large to convert to C long
- flex blazeds java_Flex使用Blazeds与Java交互及自定义对象转换详解
- 小程序的优势和劣势是什么?
- 删除IE浏览器input框自带的删除叉
- 具有深度沉浸能力的人更能有所成就
- 小程序步数解密php,微信小程序--获取微信运动步数的实例代码
- Docker基础介绍(二)
- 若依ruoyi-vue总结
热门文章
- git使用回滚,清除暂缓区,解决冲突(持续更新)
- Flask爱家租房--发布新房源(保存房屋基本信息)
- python 爬虫 包_python爬虫学习之路-抓包分析
- SQLAlchemy()分页器paginate方法
- 机器学习之EM算法的原理推导及相关知识总结
- java.lang.IllegalArgumentException: Does not contain a valid host:port authority: ignorethis
- 【C#学习笔记】使用C#中的Dispatcher
- mysql批量用trim限定_如何使用trim()并更新mysql中的所有行[复制]
- Master-Detail(主表明细),确认可以出货的SQL指令 -- Not Exists
- 使用export/import导出和导入docker容器