编程语言
首页 > 编程语言> > Day 26:Python 中的装饰器是什么?

Day 26:Python 中的装饰器是什么?

作者:互联网

Python 中使用 @函数名字,放在某些函数上面,起到增强它们功能的作用。

def hi(name="piayie"):
    def greet():
        return "now you are in the greet() function"
 
    def welcome():
        return "now you are in the welcome() function"
 
    if name == "pieyie":
        return greet
    else:
        return welcome
 
a = hi()
print(a)

output:
<function hi.<locals>.greet at 0x6fff96c98c8>

注意返回的是 greet 和 welcome,而不是 greet() 和 welcome()。这是因为当你把一对小括号放在后面,这个函数就会执行;然而如果你不放括号在它后面,那它可以被到处传递,并且可以赋值给别的变量而不去执行它。

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

output:
I am doing some boring work before executing hi()
hi piayie!

 

增强函数功能,方便重复调用,但是函数本身的功能的执行也是需要的,并不是说把函数直接变成了另一个函数

装饰器有助于让我们的代码更简短,也更Pythonic。

会使得代码更加简洁,代码的复用性大大提升。

因此,装饰器被广泛使用。Python 中到处都能看到装饰器的身影。

不光在 Python,其他语言如 Java 中,装饰器被称作注解,也被应用广泛。

Python 前端最流行的框架之一 Flask,URL 地址和 controller 层的映射处理函数,就是使用装饰器。

# import Flask,同时创建一个 app:
from flask import Flask
app = Flask(__name__)

#URL 路径 / 与处理函数建立映射关系,正是通过装饰器 app.route 控制层处理响应前端,并返回字符串 hello world 到前端界面。
@app.route('/')
def index():
    return "hello world"




# Python 支持异步编程,从中也能看到装饰器的身影

# 使用装饰器 @asyncio.coroutine,将一个生成器asyncio_open_conn 标记为 coroutine 类型
import asyncio

@asyncio.coroutine
def asyncio_open_conn(host:str):
    print("using asyncio builds web connection")
    connect = yield from asyncio.open_connection(host, 80)
    print("get connect of %s"%(host,))

loop = asyncio.get_event_loop()
connections = [asyncio_open_conn(host) for host in [
    'www.sina.com', 'www.baidu.com']]
loop.run_until_complete(asyncio.wait(connections))
loop.close()

output:
using asyncio builds web connection
using asyncio builds web connection
get connect of www.sina.com
get connect of www.baidu.com

下面介绍几个装饰器例子来理解什么是装饰器

call_print 装饰器

# 定义函数 call_print,它的入参 f 为一个函数,它里面内嵌一个函数 g,并返回函数 g
def call_print(f):
    def g():
        print('you\'re calling %s function' % (f.__name__,))
    return g