引言:

函数和装饰器好比程序界的加工厂:

1、函数一般可用来加工一种或者多种数据类型的数据:字符串、数字、列表、字典等

举一个简单例子:已知半径求面积

def s(r):
s = 3.14 * r * r
return s

调用s函数:输入4,输出半径为4的圆的面积。a相当于面积的容器

a = s(4)
print(a)

2、装饰器是用来装饰函数的函数。其需要输入的原材料为某个函数

以下是装饰器的固定格式:

 def timer(func):
def inner(*args,**kwargs):
'''执行函数之前要做的'''
re = func(*args,**kwargs)
'''执行函数之后要做的'''
return re
return inner

timer函数是一个进化函数的函数:装饰器

timer是用来加工函数的,即产品应该也应该是函数(进化版)。

def timer(func):
#
#func的进化过程
#
return inner # 强化变身版func

上面的代码就比较容易理解了,就是定义一个函数去强化函数,得到一个强化func

接下来,我们就深入研究func的强化过程:

1、你return了一个inner函数,他不是凭空产生的,就是石猴还不远万里去学艺,并取了了名字叫孙悟空呢。

所以一开始你要:

def inner(*args,**kwargs):   # inner 今天成立了

我们知道inner是为了强化加工厂func的,所以inner需要的原材料必须是和func一样的。启动万能可变参数(*args,**kwargs)

    def inner(*args,**kwargs):
'''执行函数之前要做的''' # 强化1
re = func(*args,**kwargs) # 这个是原函数的核心部件,你就不要随便动他了。。。否则,你为啥不自己写一个程序。。。
'''执行函数之后要做的''' #强化2
return re

我们再讲一下为啥要要有  re 这个东西,还要return

因为这就是func原工厂生产的东西啊。。。没有return 你就丢了啊

到了最后变身的 时候了。。。

hahaha之前是一个小小加工厂,注册资金只有10w

后来王思聪老公投资了1亿,hahaha立马走上人生巅峰

inner 是哈哈哈被timer(王思聪)强化后的hahaha

这时候工商局找来了。。。指着inner说,你不就是原来的hahaha么,必须在我这更改相关信息,但是名字就不能改了

认证:hahaha = timer(hahaha) # 注册资金1亿

后来工商局发现经常性工厂升级,所以后来就直接在营业执照上盖了个戳

@timer

讲了这么多,就是为了加深大家的理解,其实记住下面的就好了

def wrapper(func):

def inner(*args,**kwargs):#定义函数的时候——*参数的聚合

ret = func(*args,**kwargs)  #调用函数的时候——*参数的打散

#func是被装饰的函数,ret是被装饰函数的返回值

return ret #把被装饰的函数的返回值返回给调用者

return inner

带参数的装饰器

假如你有成千上万个函数使用了一个装饰器,现在你想把这些装饰器都取消掉,你要怎么做?

def outer(flag):
def timer(func):
def inner(*args,**kwargs):
if flag:
print('''执行函数之前要做的''')
re = func(*args,**kwargs)
if flag:
print('''执行函数之后要做的''')
return re
return inner
return timer @outer(False)
def func():
print(111) func()

多个装饰器装饰同一个函数

def wrapper1(func):
def inner():
print('wrapper1 ,before func')
func()
print('wrapper1 ,after func')
return inner def wrapper2(func):
def inner():
print('wrapper2 ,before func')
func()
print('wrapper2 ,after func')
return inner @wrapper2
@wrapper1
def f():
print('in f') f()

附加:关于可变参数的应用

#动态参数
def ccc(*args):#1,2,3,4,5
print(args) ccc(1,2,3,4,5)#按位置传参数 t = (1,2,3,4,5)
ccc(t) ((1, 2, 3, 4, 5),)
ccc(*t) (1, 2, 3, 4, 5) def ddd(**kwargs):
print(kwargs) # ddd(k = 'a',j = 'b')#按关键字传参数 def eee(*args,**kwargs):
print(args,kwargs) # eee(12,123) #先按位置传参,再按关键字传参 def ccc(*args):
print('ccc:',args) #(1,2,3,4,5)
def inner(a,b,c,d,e):
print('inner',a,b,c,d,e)
inner(*args) #*(1,2,3,4,5) 打散 def inner(a,b,c,d,e):
print('inner',a,b,c,d,e)
# ccc(1,2,3,4,5)
# inner(1,2,3,4,5)

Python函数加工厂-装饰器的更多相关文章

  1. Python函数06/装饰器

    Python函数06/装饰器 目录 Python函数06/装饰器 内容大纲 1.装饰器 1.1 开放封闭原则 1.2 装饰器 2.今日练习 内容大纲 1.装饰器 1.装饰器 1.1 开放封闭原则 扩展 ...

  2. python——函数之装饰器

    1 问题 实际生活中,我们很难一次性就把一个函数代码写得完美无缺.当我们需要对以前的函数添加新功能时,我们应该怎么做? 2 问题解决思路 (1)可以直接修改原来的函数,在函数内直接修改.当我们对多个函 ...

  3. python函数、装饰器、迭代器、生成器

    目录: 函数补充进阶 函数对象 函数的嵌套 名称空间与作用域 闭包函数 函数之装饰器 函数之迭代器 函数之生成器 内置函数 一.函数补充进阶 1.函数对象:  函数是第一类对象,即函数可以当作数据传递 ...

  4. Python 函数之装饰器

    1.函数 #### 第一波 #### def foo(): print 'foo' foo #表示是函数 foo() #表示执行foo函数 #### 第二波 #### def foo(): print ...

  5. python函数闭包-装饰器-03

    可调用对象 callable()  # 可调用的(这个东西加括号可以执行特定的功能,类和函数) 可调用对象即  callable(对象)  返回为  True  的对象 x = 1 print(cal ...

  6. Python函数的装饰器修复技术(@wraps)

    @wraps 函数的装饰器修复技术,可使被装饰的函数在增加了新功能的前提下,不改变原函数名称,还继续使用原函数的注释内容: 方便了上下文环境中不去更改原来使用的函数地方的函数名: 使用方法: from ...

  7. Python函数的装饰器修复技术(@wraps)

    @wraps 函数的装饰器修复技术,可使被装饰的函数在增加了新功能的前提下,不改变原函数名称,还继续使用原函数的注释内容: 方便了上下文环境中不去更改原来使用的函数地方的函数名: 使用方法 from ...

  8. Python函数的装饰器

    函数的装饰器. 1. 装饰器 开闭原则: 对功能的扩展开放 对代码的修改是封闭 通用装饰器语法: def wrapper(fn): def inner(*args, **kwargs): # 聚合 & ...

  9. python 函数之装饰器,迭代器,生成器

    装饰器 了解一点:写代码要遵循开发封闭原则,虽然这个原则是面向对象开发,但也适用于函数式编程,简单的来说,就是已经实现的功能代码不允许被修改但 可以被扩展即: 封闭:已实现功能的代码块 开发:对扩张开 ...

随机推荐

  1. [转]wordpress安装插件的3种方式

    WordPress插件安装方法有几种?WordPress是一种使用PHP语言开发的博客平台,有些用户不知道怎么安装WordPress插件和主题的,所以今天小编就为大家介绍几种WordPress插件安装 ...

  2. Android开发 - 图形化生成的贝塞尔插值器

    基于三次方贝塞尔曲线的插值器 在动画开发过程中,经常需要使用到插值器来满足我们的动画设计需求.然而,官方提供的插值器并不能满足所有的需求,所以我们需要自定义插值器. 下面介绍的三次方贝塞尔曲线的插值器 ...

  3. jxta-amalto

    前几天在网络上搜索jxta的消息,发现jxta 2.8x已经启动了,官方地址http://chaupal.github.io/ 在浏览其邮件列表时,意外发现一老外基于jxta 2.6修改的一版, 可在 ...

  4. Easyui Datagrid的Rownumber行号显示问题

    Datagrid中当你的行数据超过9999时,第一列的行号rownumber将会因为表格内容过长而导致无法显示全部数字, 这一点Easyui无法做到自适应 所以需要进行修改,这里扩展一个方法就行了. ...

  5. python 糗事百科实例

    爬取糗事百科段子,假设页面的URL是 http://www.qiushibaike.com/8hr/page/1 要求: 使用requests获取页面信息,用XPath / re 做数据提取 获取每个 ...

  6. Gabor变换、Gabor滤波器

    D.Gabor 1946年提出 窗口Fourier变换,为了由信号的Fourier变换提取局部信息,引入了时间局部化的窗函数. 由于窗口Fourier变换只依赖于部分时间的信号,所以,现在窗口Four ...

  7. Laravel5.1 登录和注册

    关于登录和注册 Laravel自带了一套组件实现了这一功能,我们只需要实现简单的视图即可. AuthController是专门管理用户注册和登录的. PassWordController是重置密码用的 ...

  8. Windows平台安装最新OpenCV-2.4.9,利用Eclipse、MinGW构建C++调用OpenCV开发环境

    近期电脑重装系统了,第一件事重装OpenCV. 这次直接装最新版,2014-4-25日公布的OpenCV2.4.9版本号,下载链接: http://sourceforge.net/projects/o ...

  9. 爬虫入门【10】Pyspider框架简介及安装说明

    Pyspider是python中的一个很流行的爬虫框架系统,它具有的特点如下: 1.可以在Python环境下写脚本 2.具有WebUI,脚本编辑器,并且有项目管理和任务监视器以及结果查看. 3.支持多 ...

  10. 创建Json

    1)生成 JSON: 方法 1.创建一个 map,通过构造方法将 map 转换成 json 对象 Map<String, Object> map = new HashMap<Stri ...