Python学习 day12
一、@wraps
__name__ 查看函数的名字
__doc__ 查看函数的文档字符串
例:
def func(arg):
"""
这是一个测试函数,这里是函数说明
:param arg: 参数说明
:return: 返回值说明
"""
return arg print(func.__name__)
print(func.__doc__)
结果:

但是,经过装饰器装饰的函数,我们知道虽然调用与原来一致,但原函数名实际指向的却是装饰器中的inner函数,所以在调用__name__和__doc__时,得到的结果,如下:
def wrapper(func):
def inner(*args, **kwargs):
"""
这是一个装饰器内部函数,对原函数进行装饰
:param args: 原函数中的位置传参
:param kwargs: 原函数中的按关键字传参
:return: 返回原函数执行后的结果
"""
print("在原函数之前")
ret = func(*args, **kwargs)
print("在原函数之后")
return ret
return inner @wrapper
def test(arg):
"""
这是一个测试函数,这里是函数说明
:param arg: 参数说明
:return: 返回值说明
"""
return arg print(test.__name__)
print(test.__doc__)
结果:

可以看到,被装饰的函数调用__name__和__doc__得到的不再是原函数的名称和文档字符串
为了解决这个问题,我们引入wraps装饰inner函数,就可以正常获取元函数的函数名和文档字符串了,如下:
from functools import wraps def wrapper(func):
@wraps(func) # 用wraps装饰inner函数
def inner(*args, **kwargs):
"""
这是一个装饰器内部函数,对原函数进行装饰
:param args: 原函数中的位置传参
:param kwargs: 原函数中的按关键字传参
:return: 返回原函数执行后的结果
"""
print("在原函数之前")
ret = func(*args, **kwargs)
print("在原函数之后")
return ret
return inner @wrapper
def test(arg):
"""
这是一个测试函数,这里是函数说明
:param arg: 参数说明
:return: 返回值说明
"""
return arg print(test.__name__)
print(test.__doc__)
执行以上代码,得到:

二、带参数的装饰器
在有些情况下,需要使用带参数的装饰器,把外部的变量值传入装饰器中,进行相关操作。
举例:如有一种情况,项目经理需要测试每个人设计的函数的执行时间,以此来对每个人的函数进行评测,这时就需要增加函数执行的计时功能,需要用到装饰器。在评测结束后,项目经理又要求将计时功能去掉,这如果把装饰器再一个个去除就会非常麻烦,因此需要一种变通的方法能保证需要的时候增加装饰器,不需要时去掉。
就这个例子设计一个装饰器,我们有如下方法:
import time FLAG = True # 标志位 def timmer_out(FLAG):
def timmer(func):
def inner(*args, **kwargs):
if FLAG: # FLAG为True时,增加计时功能
start = time.time()
ret = func(*args, **kwargs)
end = time.time()
print(end - start)
return ret
else: # False时不装饰
return func(*args, **kwargs)
return inner
return timmer def func1():
print("执行func1")
time.sleep(3)
print("func1结束") @timmer_out(FLAG) # 语法糖,实际如下面func1
def func2():
print("执行func2")
time.sleep(5)
print("func2结束") t = timmer_out(FLAG)
func1 = t(func1)
func1()
func2()
结果:

若FLAG=False,结果:

可以看到,通过控制FLAG的值就可以控制是否给原函数增加装饰,解决了问题。
其实timmer_out函数就做了一个利用闭包传参的功能,若没有timmer_out这个外部函数,里面inner想使用全局变量FLAG的值在python中也是可以的,但这样的用法不是程序设计推荐的,不如由外部函数timmer_out传入更规范。
三、多个装饰器装饰一个函数
多个装饰器装饰一个函数依然类似java中的过滤器和拦截器,与aop思想一致,因多个装饰器都对函数有增加功能,那执行的顺序是什么呢,如:
def wrapper1(func):
def inner(*args, **kwargs):
print("-------wrapper1在函数调用前--------")
ret = func(*args, **kwargs)
print("-------wrapper1在函数调用后--------")
return ret
return inner def wrapper2(func):
def inner(*args, **kwargs):
print("-------wrapper2在函数调用前--------")
ret = func(*args, **kwargs)
print("-------wrapper2在函数调用后--------")
return ret
return inner def wrapper3(func):
def inner(*args, **kwargs):
print("-------wrapper3在函数调用前--------")
ret = func(*args, **kwargs)
print("-------wrapper3在函数调用后--------")
return ret
return inner @wrapper2
@wrapper1
@wrapper3
def func():
print("我是被装饰函数") func()
结果:

可看到,装饰器的执行顺序是根据装饰顺序来的:2-1-3-func-3-1-2
四、零散知识点
1、函数的注释
在python中写的函数,也有函数注释,类似java的方法注释,用于说明函数的主要功能,参数和返回值。
具体写法:
def func(arg):
"""
这是一个测试函数,这里是函数说明
:param arg: 参数说明
:return: 返回值说明
"""
return arg
在pycharm中函数下面直接输入三个”工具会自动显示函数注释的内容
2、os.path.getsize()
从os模块引入getsize()函数,用于判断文件大小。例:
import os
print(os.path.getsize('test')) # 获取test文件的大小,单位byte
五、其他
课程老师推荐了两本书《Python核心编程》、《流畅的python》,可以买来看看。
Python学习 day12的更多相关文章
- python学习Day12 函数的默认值、三元表达式、函数对象(函数名)的应用场景、名称空间与作用域
复习 1.字符串的比较: -- 按照从左往右比较每一个字符,通过字符对应的ascii进行比较 2. 函数的参数 : 1)实参与形参: -- 形参:在函数定义时()中出现的参数 ...
- python学习-day12:列表、元祖、字典介绍和内置
list:列表 >>>----可以被修改.修改成元素,元素可以使单独的数字,也可以是:新的list. 通过:链表..每个元素存储的时候,同时会指向下一个元素. 二.list编辑修改方 ...
- python学习day12
目录 html结构与标签 css样式 html结构之head <head> 标签用于定义文档的头部,它是所有头部元素的容器.<head> 中的元素可以引用脚本.指示浏览器在 ...
- python学习day12 函数Ⅳ (闭包&内置模块)
函数Ⅳ (闭包&内置模块) 1.内置函数(补充) lambda表达式也叫匿名函数. 函数与函数之间的数据互不影响,每次运行函数都会开一个辟新的内存. item = 10 def func(): ...
- python学习 day12 (3月18日)----(装饰器内置函数)
读时间函数: # import time # def func(): # start_time = time.time() # 代码运行之前的时间 # print('这是一个func函数') # ti ...
- Python学习-day12 Mysql
MYSQ数据库的安装使用 Linux/UNIX上安装Mysql Linux平台上推荐使用RPM包来安装Mysql,MySQL AB提供了以下RPM包的下载地址: MySQL - MySQL服务器.你需 ...
- python学习(day1-2)
python 学习(day - 1-2 ) 变量:将运算的中间结果暂存到内存,以便后续程序调⽤. 变量的命名规则: 1, 变量由字⺟, 数字,下划线搭配组合⽽成 2, 不可以⽤数字开头,更不能是全数字 ...
- python学习博客地址集合。。。
python学习博客地址集合... 老师讲课博客目录 http://www.bootcdn.cn/bootstrap/ bootstrap cdn在线地址 http://www.cnblogs. ...
- 【目录】Python学习笔记
目录:Python学习笔记 目标:坚持每天学习,每周一篇博文 1. Python学习笔记 - day1 - 概述及安装 2.Python学习笔记 - day2 - PyCharm的基本使用 3.Pyt ...
随机推荐
- SpringMVC的问题No mapping found for HTTP request with URI
做了一个屏蔽进数据库的操作: Applicaition.xml配置: <?xml version="1.0" encoding="UTF-8"?> ...
- 版本控制-https svn服务器搭建和常用命令(centos 6.3)
Svn是比较优秀的版本控制工具,虽然功能和性能上无法和Git媲美,但由于其容易搭建和使用的特性,所以在各个小公司还是很受欢迎的.使用Git可参考<版本控制-Git服务器搭建和常用命令使用> ...
- unity 小地图的制作
利用 Transform.InverseTransformDirection 变换位置从世界坐标到自身坐标. 以第一人称控制器为坐标原点(忽视y轴),x轴z轴转为屏幕坐标. 若物体在地图范围外,可以 ...
- 编写高质量代码改善C#程序的157个建议——建议142:总是提供有意义的命名
建议142:总是提供有意义的命名 除非有特殊原型,否则永远不要为自己的代码提供无意义的命名. 害怕需要过长的命名才能提供足够的意义?不要怕,其实我们更介意的是在代码的时候出现一个iTemp. int ...
- 团体程序设计天梯赛L2-002 链表去重 2017-03-22 18:12 25人阅读 评论(0) 收藏
L2-002. 链表去重 时间限制 300 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 给定一个带整数键值的单链表L,本题要求你编写程序,删除 ...
- CodeForces 907E Party(bfs+状压DP)
Arseny likes to organize parties and invite people to it. However, not only friends come to his part ...
- shiro注解@RequiresPermissions多权限任选一参数用法
@RequiresPermissions(value={"xxx:xxx","xxx:xxx"},logical=Logical.OR)
- 一个自定义MVP .net框架 AngelFrame
摘要:本篇是本人在完成.net平台下一个项目时,对于MVP框架引发的一些思考,以及开发了一个小型的配置型框架,名字叫作AngelFrame.这个项目属于前端桌面管理系统的一部分,最终要集成进去. 关键 ...
- Transaction And Lock--存在嵌套事务吗?
在很多编程语言中,可以实现嵌套,但在TSQL中,可以实现嵌套事务吗? 答案:不可以 虽然我们可以写如下code: CREATE TABLE #TB1 ( ID INT ) --创建事务1 BEGIN ...
- C# 调用C++动态库注意事项
C# 调用C++动态库注意事项 最近项目上需要在C#中调用C++,期间遇到不少坑,总结如下: 1.in const char* 对应C#中string 或 IntPtr 2.out const ...