12装饰器及*args,**kwargs
注:参数和返回值都是一个函数。
1,无参数
def decotare1(func):
def wrapper():
print("First")
func()
return wrapper #注意,这里的wrapper没有打括号就证明是返回了函数体,而非函数运行结果。
#无参数 @decotare1 def run(): print('run!') run() #结果: First run!
2,有参数
def decotare1(func):
def wrapper(a,b): #3
print("First")
func(a,b) #2
return wrapper #有参数,称为代码段1
@decotare1
def add(a,b):
c = a + b
print('结果:%s' %c)
add(1,2) #结果:
First
结果:3
为什么上述标黄?
因为 add(1,2) 的运行就是代码段1的运行,代码段1相当于运行了“decotare1(add(a,b))“这个函数,而他返回了wrapper函数
你的add(a,b)本身是带两个参数的,那么你返回的函数也应该带参数,所以#2和#3都带了参数。
3,参数不确定的时候怎么办?
from functools inport wraps #两个紫色的做固定用法,不会改变原来的意思
#因为不佳两句紫色的那么函数名字会被改变。链接20分钟左右处。
def decotare1(func):
@wraps(func)
def wrapper(*args,**kwargs):
print("First")
func(*args,**kwargs)
return wrapper #无参数
@decotare1
def run():
print("Second")
run() #1 #有参数
@decotare1
def add(a,b):
c = a + b
print('结果:%s' %c)
add(1,2) #2
上述代码对于无参数的run,和有参数的add来说都能直接调用,归功于:*args,**kwargs。
这里详细介绍下*args,**kwargs:
1,* 的意义
def fun(a,b,c):
... print a,b,c
l = [1,2,3]
>>>fun(*l)
它拆开*后面的数列l的数值作为位置参数,并把这些位置参数传给函数’fun’来调用。
注意:l与对应的fun函数中的参数个数对应。 2,*args 的意义
def fun(*args):
... print args
>>>fun() #这个函数中可以带任意个参数。
在这里,”args”是个元组。调用函数打印”args”时,他会打印元组中包含的所有数值。 def fun(a,*args):
... print args
>>>fun() #这个函数中也可以带任意个参数。 3,** 的意义
使用”**”调用函数,这种方式我们需要一个字典.
注意:在函数调用中使用”*”,我们需要元组;在函数调用中使用”**”,我们需要字典。
def fun(a, b, c):
... print a, b, c
>>> d={'b':5, 'c':7}
>>> fun(1, **d)
1 5 7
但是:
>>> d = {'a':7, 'b':3, 'c':8, 'd':90}
>>> fun(**d)
Traceback (most recent call last):出错了。
fun(**d)等同于fun(a=7, b=3, d=90).传给函数”fun”想要的参数个数,但参数列表中并没有’d’,调用中’d’键值参数传给函数导致TypeError. 4,**kwargs的意义
用”**kwargs”定义函数,kwargs接收除常规参数列表职位的键值参数字典。在这里’kwargs’是个字典。所以字典就需要对应关系,比如fun里没C你传个C进去就没有用。
def fun(a, **kwargs):
... print a, kwargs
此函数只用一个位置参数,因为常规参数列表中只有一个变量’a’.但是通过”**kwargs”,可以传多个键值参数。
>>> fun(1, {'b':2, 'c':34})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: fun() takes exactly 1 argument (2 given)
正如错误提示,函数’fun’只需要一个位置参数,却给了两个。尽管’kwargs’接收键值参数作为一个字典,但你不能传一个字典作为位置参数给’kwargs’.你可以像下面那样调用:
>>> fun(1, **{'b':2, 'c':34})
12装饰器及*args,**kwargs的更多相关文章
- day 12 装饰器
nonlocal关键字 # 作用:将 L 与 E(E中的名字需要提前定义) 的名字统一# 应用场景:如果想在被嵌套的函数中修改外部函数变量(名字)的值# 案例:def outer(): n ...
- Day 12 装饰器,开发封闭.
一.什么是装饰器 装饰器本质上就是一个python函数,他可以让其他函数在不需要做任何代码变动的前提下,增加额外的功能,装饰器的返回值也是一个函数对象. 装饰器的应用场景:比如插入日志,性能测试,事务 ...
- python 基础篇 12 装饰器进阶
本节主要内容:1. 通⽤装饰器回顾2. 函数的有⽤信息3. 带参数的装饰器4. 多个装饰器同时装饰⼀个函数 ⼀. 通⽤装饰器的回顾开闭原则: 对增加功能开放. 对修改代码封闭装饰器的作⽤: 在不改变原 ...
- Python带参数的装饰器
在装饰器函数里传入参数 # -*- coding: utf-8 -*- # 2017/12/2 21:38 # 这不是什么黑魔法,你只需要让包装器传递参数: def a_decorator_passi ...
- python装饰器三种装饰模式的简单理解
学设计模式中有个装饰模式,用java实现起来不是很难,但是远远没有python简单,难怪越来越火了! 这里就简单讨论下python的几种装饰模式: 一 无参装饰器: # 装饰器 import time ...
- Python 闭包及装饰器
闭包是指延伸了作用域的函数. 自由变量(free variable) 指未在本地作用域中绑定的变量 函数装饰器用于在源码中标记函数, 以某种方式增强函数的行为. 装饰器实质,把被装饰的函数替换为新函数 ...
- 闭包&装饰器
闭包 1.函数引用 def test(): print('--test--') # 调用函数 test() # 引用函数 ret = test print(id(ret)) print(id(test ...
- python :编写装饰器
简单装饰器 def log_time(func): # 此函数的作用时接受被修饰的函数的引用test,然后被内部函数使用 def make_decorater(): print('现在开始装饰') f ...
- 函数与装饰器Python学习(三)
1.1 文件处理 1.1.1 打开文件过程 在Python中,打开文件,得到文件句柄并赋值给一个变量,默认打开模式就为r f=open(r'a.txt','w',encoding='utf-8') p ...
随机推荐
- ansible-playbook-roles目录结构
1. ansible-角色-roles目录结构 角色是基于已知文件结构自动加载某些vars_files,任务和处理程序的方法.按角色对内容进行分组还可以轻松与其他用户共享角色. ...
- eclipse 配置opencv
1 准备 eclipse 2017 JDK1.8 opencv 4.40 2 配置 新建java工程 添加jar包 选择opencv-xxx.jar包 加入原生库 选择原生库位置 确认即可,测试 新建 ...
- JVM系列【2】Class文件结构
JVM系列笔记目录 虚拟机的基础概念 class文件结构 class文件加载过程 jvm内存模型 JVM常用指令 GC与调优 如何查看class字节码文件 在idea中可以通过插件BinEd来查看二进 ...
- linux centos 03
linux用户权限相关 root用户 相当于qq群的群主 sudo命令 相当于qq群的管理员 普通用户 相当于qq群的 水军 超级用户root的UID是 0 组ID也是 0 普通用户的UID ...
- python接口测试之读取配置文件
1.python使用自带的configparser模块用来读取配置文件,配置文件可以为.conf或.ini结尾 在使用前需要先安装该模块,使用pip安装即可 2.新建一个名为a.conf的配置文件 a ...
- 分布式锁结合SpringCache
1.高并发缓存失效问题: 缓存穿透: 指查询一个一定不存在的数据,由于缓存不命中导致去查询数据库,但数据库也无此记录,我们没有将此次查询的null写入缓存,导致这个不存在的数据每次请求都要到存储层进行 ...
- 第八章 nginx基础介绍
一.nginx概述 nginx是一个开源且高性能.可靠的http web服务.代理服务. 开源:直接获取源代码 高性能:支持海量并发 可靠:服务稳定 二.nginx特点 1.高性能高并发 性能高,支持 ...
- 聊聊简单又灵活的权限设计(RBAC)
你:我看完能知道个啥?我:也就以下两点吧一. 了解基于 RBAC 思路的表设计二. 表数据在实际开发场景中是如何使用的你:我觉得那应该还有点干货吧我:我不要你觉得,我要我觉得 (͡ ͡° ͜ つ ͡͡ ...
- Navigator 的使用方法
对象属性 属性 Navigator 说明 appCodeName 返回浏览器的代码名 appName 返回浏览器的名称 appVersion 返回浏览器的平台和版本信息 cookieEnabled 返 ...
- Django采坑日志(django2.0)
使用Mariadb时出现的问题 "Unknown system variable 'transaction_isolation'" 解决办法:修改django/db/backend ...