def hi(name="yasoob"):
return "hi " + name
print(hi())
# 我们甚至可以将一个函数赋值给一个变量,比如
greet=hi
# 我们这里没有在使用小括号,因为我们并不是在调用hi函数
# 而是在将它放在greet变量里头。我们尝试运行下这个
print(greet(),greet,sep='\n')
gre=hi()
print(gre)
'''
以上输出为:
hi yasoob
hi yasoob
<function hi at 0x00000240E0E71160>
hi yasoob
'''
# 如果我们删掉旧的hi函数,看看会发生什么!
del hi
# print(hi())
# outputs: NameError
print(greet())
# outputs: 'hi yasoob'
全部输出为:
'''
hi yasoob
hi yasoob
<function hi at 0x00000240E0F3DEE0>
hi yasoob
hi yasoob
'''

参考:https://www.runoob.com/w3cnote/python-func-decorators.html

在函数中定义函数

刚才那些就是函数的基本知识了。我们来让你的知识更进一步。在 Python 中我们可以在一个函数中定义另一个函数:

def hi(name="yasoob"):
print("now you are inside the hi() function") def greet1():
return "now you are in the greet1() function" def welcome():
return "now you are in the welcome() function" print(greet1())
print(welcome())
print("now you are back in the hi() function") print(hi())
# output:now you are inside the hi() function
# now you are in the greet1() function
# now you are in the welcome() function
# now you are back in the hi() function
# None # 上面展示了无论何时你调用hi(), greet1()和welcome()将会同时被调用。
# 然后greet1()和welcome()函数在hi()函数之外是不能访问的,比如:
greet1()
# outputs: NameError: name 'greet1' is not defined

那现在我们知道了可以在函数中定义另外的函数。也就是说:我们可以创建嵌套的函数。现在你需要再多学一点,就是函数也能返回函数。  

从函数中返回函数

其实并不需要在一个函数里去执行另一个函数,我们也可以将其作为输出返回出来:

def hi(name="yasoob"):
def greet1():
return "now you are in the greet1() function" def welcome():
return "now you are in the welcome() function" if name == "yasoob":
return greet1
else:
return welcome a = hi()
print(a)
#outputs: <function greet at 0x7f2143c01500> #上面清晰地展示了`a`现在指向到hi()函数中的greet1()函数
#现在试试这个 print(a())
#outputs: now you are in the greet1() function

再次看看这个代码。在 if/else 语句中我们返回 greet 和 welcome,而不是 greet() 和 welcome()。为什么那样?这是因为当你把一对小括号放在后面,这个函数就会执行;然而如果你不放括号在它后面,那它可以被到处传递,并且可以赋值给别的变量而不去执行它。 你明白了吗?让我再稍微多解释点细节。

当我们写下 a = hi(),hi() 会被执行,而由于 name 参数默认是 yasoob,所以函数 greet 被返回了。如果我们把语句改为 a = hi(name = "ali"),那么 welcome 函数将被返回。我们还可以打印出hi()(),这会输出 now you are in the greet() function

def hi(name="yasoob"):
def greet1():
return "now you are in the greet1() function" def welcome():
return "now you are in the welcome() function" if name == "yasoob":
return greet1
else:
return welcome a = hi()
print(a,hi()(),sep='\n') 输出为:
<function hi.<locals>.greet1 at 0x00000240E0EAAAF0>
now you are in the greet1() function

将函数作为参数传给另一个函数

def hi():
return "hi yasoob!" def doSomethingBeforeHi(func):
print("I am doing some boring work before executing hi()")
print(func()) doSomethingBeforeHi(hi)
#outputs:I am doing some boring work before executing hi()
# hi yasoob!

现在你已经具备所有必需知识,来进一步学习装饰器真正是什么了。装饰器让你在一个函数的前后去执行代码。

你的第一个装饰器

在上一个例子里,其实我们已经创建了一个装饰器!现在我们修改下上一个装饰器,并编写一个稍微更有用点的程序:

def a_new_decorator(a_func):

    def wrapTheFunction():
print("I am doing some boring work before executing a_func()") a_func() print("I am doing some boring work after executing a_func()") return wrapTheFunction def a_function_requiring_decoration():
print("I am the function which needs some decoration to remove my foul smell") a_function_requiring_decoration()
#outputs: "I am the function which needs some decoration to remove my foul smell" a_function_requiring_decoration = a_new_decorator(a_function_requiring_decoration)
#now a_function_requiring_decoration is wrapped by wrapTheFunction() a_function_requiring_decoration()
#outputs:I am doing some boring work before executing a_func()
# I am the function which needs some decoration to remove my foul smell
# I am doing some boring work after executing a_func()

你看明白了吗?我们刚刚应用了之前学习到的原理。这正是 python 中装饰器做的事情!它们封装一个函数,并且用这样或者那样的方式来修改它的行为。

现在你也许疑惑,我们在代码里并没有使用 @ 符号?那只是一个简短的方式来生成一个被装饰的函数。这里是我们如何使用 @ 来运行之前的代码:  

@a_new_decorator
def a_function_requiring_decoration():
"""Hey you! Decorate me!"""
print("I am the function which needs some decoration to "
"remove my foul smell") a_function_requiring_decoration()
#outputs: I am doing some boring work before executing a_func()
# I am the function which needs some decoration to remove my foul smell
# I am doing some boring work after executing a_func() #the @a_new_decorator is just a short way of saying:
a_function_requiring_decoration = a_new_decorator(a_function_requiring_decoration)

  

  

Python装饰器Decorators的更多相关文章

  1. 【低门槛 手把手】python 装饰器(Decorators)原理说明

    本文目的是由浅入深地介绍python装饰器原理 装饰器(Decorators)是 Python 的一个重要部分 其功能是,在不修改原函数(类)定义代码的情况下,增加新的功能 为了理解和实现装饰器,我们 ...

  2. Python 装饰器(Decorators) 超详细分类实例

        Python装饰器分类 Python 装饰器函数: 是指装饰器本身是函数风格的实现; 函数装饰器: 是指被装饰的目标对象是函数;(目标对象); 装饰器类 : 是指装饰器本身是类风格的实现; 类 ...

  3. Python装饰器(Decorators )

    http://book.pythontips.com/en/latest/decorators.html 在<Built-in Functions(3.6)>和<Python上下文管 ...

  4. 关于python装饰器(Decorators)最底层理解的一句话

    一个decorator只是一个带有一个函数作为参数并返回一个替换函数的闭包. http://www.xxx.com/html/2016/pythonhexinbiancheng_0718/1044.h ...

  5. Python装饰器与面向切面编程

    今天来讨论一下装饰器.装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数 ...

  6. python -- 装饰器的高级应用

    装饰器和装饰器模式装饰器模式是面向对象的一种设计模式,支持将行为动态增加到已经存在的对象上.当装饰一个对象的时候,就表示独立与其他类实例对象,为该对象扩展了新的功能. python的装饰器不是装饰器模 ...

  7. Python第二十六天 python装饰器

    Python第二十六天 python装饰器 装饰器Python 2.4 开始提供了装饰器( decorator ),装饰器作为修改函数的一种便捷方式,为工程师编写程序提供了便利性和灵活性装饰器本质上就 ...

  8. python装饰器的详细解析

    什么是装饰器? python装饰器(fuctional decorators)就是用于拓展原来函数功能的一种函数,目的是在不改变原函数名(或类名)的情况下,给函数增加新的功能. 这个函数的特殊之处在于 ...

  9. Python高级特性: 12步轻松搞定Python装饰器

    12步轻松搞定Python装饰器 通过 Python 装饰器实现DRY(不重复代码)原则:  http://python.jobbole.com/84151/   基本上一开始很难搞定python的装 ...

随机推荐

  1. 通过面试题学JavaScript知识(1)

    // a 是多少的时候 可以让下面的打印ok if(a == 1 && a == 2 && a ==3){ console.log('ok') } 分析1: == 比较 ...

  2. docker 国内镜像源

    参考:docker 国内镜像源 作者:Joncc Linux环境 # vi /etc/docker/daemon.json { "registry-mirrors": [" ...

  3. 爬虫---scrapy架构和原理

    scrapy是一个为了爬取网站数据, 提取结构性数据而编写的应用框架, 它是基于Twisted框架开发而来, 而Twisted框架是事件驱动的, 比较适合异步代码. 对会阻塞线程的操作, 包括访问数据 ...

  4. B. Build the Permutation

    题目分析:我们先简单的分析一下这道题是在干什么啊,给我们三个整数n,a,b,问我们能否构造这样的排列使得序列中有a个极大值,b个极小值,能的话就给出任意一种可能的情况,不能的话就输出-1: 其实一开始 ...

  5. JavaScript学习总结9

    今天学习了表单提交,JQuery部分知识

  6. 一键智能Mock,你值得拥有

    ​ 大家好呀,我是一名苦逼的前端开发工程师,为啥苦逼呢,这不,项目下周就要上线了,但是后端还没给我接口,没有接口我就无法调试,工作停滞不前,我也只能坐着干着急. 我报告给了我的老板山哥: 老板,这后端 ...

  7. Sql语言学习——DDl

    DDL:操作数据库.表 1. 操作数据库:CRUD 1. C(Create):创建 * 创建数据库: * create database 数据库名称; * 创建数据库,判断不存在,再创建: * cre ...

  8. 03. 树莓派初始配置——安装vim编辑器

    安装vim编辑器 树莓派系统默认是不带vim编辑器的,默认安装的vi编辑器在编辑文档的时候用得特别不舒服,对人体的血压和树莓派的寿命影响较大. 解决办法:一行命令 1. 安装vim编辑器 sudo a ...

  9. Docker极简入门:使用Docker-Compose 搭建redis集群

    为了构建一个集群,我们首先要让 redis 启用集群模式 一个简单的配置文件如下redis.conf # redis.conf file port 6379 cluster-enabled yes c ...

  10. Flatbuffers学习

    flatbuffers简介 FlatBuffers 是一个(二进制 buffer)序列化开源库,由 Google 开源现在它支持C++, C#, C, Go, Java, Kotlin, JavaSc ...