笔记-python-装饰器

1.  装饰器

装饰器的实质是返回的函数对象的函数,其次返回的函数对象是可以调用的,搞清楚这两点后,装饰器是很容易理解的。

1.1.  相关概念理解

首先,要理解在Python中,函数也是一种对象

def foo(x):

print(x)

print(type(foo))

>>><class 'function'>

查看函数拥有的方法:

dir(foo)

>>>

['__call__',

'__class__',

'__closure__',

'__code__',

'__defaults__',

'__delattr__',

……]

因为函数是对象,所以函数可以作为参数传入另一个函数:

def bar(f, x):

x += 1

f(x)

bar(foo, 4) 5

1.2.  返回函数的函数

修饰函数是这样的一种函数,它接受一个函数作为输入,通常输出也是一个函数:

示例:

def loud(f):

def new_func(*args, **kw):

print('calling with', args, kw)

rtn = f(*args, **kw)

print('return value is', rtn)

return rtn

return new_func

loudlen = loud(len)

lisa = [10,20,30]

loudlen(lisa)

>>> loudlen

<function loud.<locals>.new_func at 0x000000894F4A2E18>

>>> len

<built-in function len>

解释:

在python中变量其实都是指针,对象、包括函数也是,可以相互赋值,下面也是合法的语句,在这个基础上理解容易得多;

loudlen1 = loudlen

loudlen1([10,20,30])

1.3.  使用 @

@是一个语法糖,与其说是修饰函数倒不如说是引用、调用它修饰的函数。

下面的一段代码,里面两个函数,没有被调用,也会有输出结果:

# 原理

def test(f):

print("before ...")

f()

print("after ...")

@test

def func():

print("func was called"      )

直接运行,输出结果:

before ...

func was called

after ...

上面代码只定义了两个函数: test和func。没有地方调用它们。如果没有“@test”,运行应该是没有任何输出的。

但是,Python解释器读到函数修饰符“@”的时候,后面步骤会是这样了:

1. 去调用 test函数,test函数的入口参数就是那个叫“func”的函数;

2. test函数被执行,入口参数的(也就是func函数)会被调用(执行);

换言之,修饰符带的那个函数的入口参数,就是下面的那个整个的函数。

再来看一个例子:

def test(func):

func()

print("call test")

def test1(f):

f()

print( "call test1")

def main():

@test

def fun():

print("call fun")

@test1

def fun1():

print( "call fun1")

main()

输出结果:

call fun

call fun1

call test1

call test

仔细体会调用顺序。

需要注意的:

1. 函数先定义,再修饰它;反之会编译器不认识;

2. 修饰符“@”后面必须是之前定义的某一个函数;

1.4.  多重装饰

def first(func):

print('%s() was post to first()'%func.__name__)

def _first(*args,**kwargs):

print('call the function %s() in _first().'%func.__name__)

return func(*args, **kwargs)

return _first

def second(func):

print('%s() was post second()'%func.__name__)

def _second(*args, **kwargs):

print('call the function %s() in _second.'%func.__name__)

return func(*args, **kwargs)

return _second

@first

@second

def test():

return 'hello'

输出:

test() was post second()

_second() was post to first()

>>> test()

call the function _second() in _first().

call the function test() in _second.

'hello'

>>> test

<function first.<locals>._first at 0x000000A71BCBE488>

有意思的是在视觉效果上装饰器解释时是由内向外的,而执行时是由外至内的。

上面的代码实质上相当于下面的代码:

>>> def test():

return 'hello world'

>>> test=second(test)

test() was post to second()

>>> test

<function _second at 0x000000000316D3C8>

>>> test=first(test)

_second() was post to first()

>>> test

<function _first at 0x000000000316D358>

>>> test()

Call the function _second() in _first().

Call the function test() in _second().

'hello world'

1.5.  带参数的装饰器

上面都是无参数装饰,下面是一个有参数装饰的例子:

# 装饰器带参数

def log(text):

def decorator(func):

def wrapper(*args,**kw):

print("%s %s():" %(text, func.__name__))

print(args,kw)

return func(*args, **kw)

return wrapper

return decorator

@log("execute")

def now(*args,**kwargs):

print("time.ctime()")

now(1,2,3)

输出:

execute now():

(1, 2, 3) {}

time.ctime()

上面的@log(“execute“)等价于

now = log(“execute”)(now)

>>> now

<function log.<locals>.decorator.<locals>.wrapper at 0x000000B1AA97E400>

2.  附录:

面向切面编程AOP (Aspect Oriented Programming):

AOP主要实现的目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果。

笔记-python-装饰器的更多相关文章

  1. python笔记 - day4-之装饰器

                 python笔记 - day4-之装饰器 需求: 给f1~f100增加个log: def outer(): #定义增加的log print("log") ...

  2. Python学习笔记:装饰器

    Python 装饰器的基本概念和应用 代码编写要遵循开放封闭原则,虽然在这个原则是用的面向对象开发,但是也适用于函数式编程,简单来说,它规定已经实现的功能代码不允许被修改,但可以被扩展,即: 封闭:已 ...

  3. Python 装饰器学习心得

    最近打算重新开始记录自己的学习过程,于是就捡起被自己废弃了一年多的博客.这篇学习笔记主要是记录近来看的有关Python装饰器的东西. 0. 什么是装饰器? 本质上来说,装饰器其实就是一个特殊功能的函数 ...

  4. Python 装饰器填坑指南 | 最常见的报错信息、原因和解决方案

    本文为霍格沃兹测试学院学员学习笔记. Python 装饰器简介 装饰器(Decorator)是 Python 非常实用的一个语法糖功能.装饰器本质是一种返回值也是函数的函数,可以称之为“函数的函数”. ...

  5. 关于python装饰器

    关于python装饰器,不是系统的介绍,只是说一下某些问题 1 首先了解变量作用于非常重要 2 其次要了解闭包 def logger(func): def inner(*args, **kwargs) ...

  6. python装饰器通俗易懂的解释!

    1.python装饰器 刚刚接触python的装饰器,简直懵逼了,直接不懂什么意思啊有木有,自己都忘了走了多少遍Debug,查了多少遍资料,猜有点点开始明白了.总结了一下解释得比较好的,通俗易懂的来说 ...

  7. Python 装饰器学习

    Python装饰器学习(九步入门)   这是在Python学习小组上介绍的内容,现学现卖.多练习是好的学习方式. 第一步:最简单的函数,准备附加额外功能 1 2 3 4 5 6 7 8 # -*- c ...

  8. python 装饰器修改调整函数参数

    简单记录一下利用python装饰器来调整函数的方法.现在有个需求:参数line范围为1-16,要求把9-16的范围转化为1-8,即9对应1,10对应2,...,16对应8. 下面是例子: def fo ...

  9. python 装饰器学习(decorator)

    最近看到有个装饰器的例子,没看懂, #!/usr/bin/python class decorator(object): def __init__(self,f): print "initi ...

  10. Python装饰器详解

    python中的装饰器是一个用得非常多的东西,我们可以把一些特定的方法.通用的方法写成一个个装饰器,这就为调用这些方法提供一个非常大的便利,如此提高我们代码的可读性以及简洁性,以及可扩展性. 在学习p ...

随机推荐

  1. [Freemarker] Getting Start

    Freemarker是一个模板引擎,在.NET中有类似的T4模板,FreeMarker对ASP.NET MVC也很友好,链接地址,引用官方的一幅图 模板+数据=视图 Following are the ...

  2. AJPFX总结java创建线程的三种方式及其对比

    Java中创建线程主要有三种方式: 一.继承Thread类创建线程类 (1)定义Thread类的子类,并重写该类的run方法,该run方法的方法体就代表了线程要完成的任务.因此把run()方法称为执行 ...

  3. 初始html(常用标签)

    今天我们来学习Web前端的一些知识,这一阶段需要记忆的东西相对来说比较多,需要花时间记忆以及做好练习. 一.HTML初识 1.web服务本质 import socket def main(): soc ...

  4. eclipse, idea安装lombok插件

    参考博客: https://www.cnblogs.com/quan-coder/p/8387040.html 一:在开发工具中安装插件: Eclipse: 下载地址:https://projectl ...

  5. meterpreter > sysinfo

    meterpreter > sysinfoComputer : test-VCS86VROS : Windows XP (Build 2600).Architecture : x86System ...

  6. jQuery-安装方法(2类)

    一.下载到本地,调用本地jQuery库 下载地址:http://jquery.com/download/ 共有两个版本的 jQuery 可供下载: 1.精简版:用于实际的网站中,已被精简和压缩. 2. ...

  7. 因技术垃圾直接上手groovy的工作感悟

    因为熟悉devops,用IDEA的git完成版本提交,不太喜欢公司的代码控制,从事groovy基本没有代码控制,提交就打个压缩包给指定的人. 没有持续继承,持续部署(CICD). http://xio ...

  8. IOS 隐式动画(非Root Layer)

    ● 每一个UIView内部都默认关联着一个CALayer,我们可用称这个Layer为Root Layer(根 层) ● 所有的非Root Layer,也就是手动创建的CALayer对象,都存在着隐式动 ...

  9. object-detection-crowdai数据处理

    import os file=os.listdir('/home/xingyuzhou/object-detection-crowdai') file.sort(key= lambda x:int(x ...

  10. numpy.random.shuffle(x)的用法

    numpy.random.shuffle(x) Modify a sequence in-place by shuffling its contents. Parameters: x : array_ ...