首页 > 编程 > Python > 正文

Python的装饰器使用详解

2020-02-16 01:45:50
字体:
来源:转载
供稿:网友

Python有大量强大又贴心的特性,如果要列个最受欢迎排行榜,那么装饰器绝对会在其中。

初识装饰器,会感觉到优雅且神奇,想亲手实现时却总有距离感,就像深闺的冰美人一般。这往往是因为理解装饰器时把其他的一些概念混杂在一起了。待我抚去层层面纱,你会看到纯粹的装饰器其实蛮简单直率的。

装饰器的原理

在解释器下跑个装饰器的例子,直观地感受一下。
# make_bold就是装饰器,实现方式这里略去

>>> @make_bold... def get_content():...  return 'hello world'...>>> get_content()'<b>hello world</b>'

被 make_bold 装饰的 get_content ,调用后返回结果会自动被 b 标签包住。怎么做到的呢,简单4步就能明白了。

1. 函数是对象

我们定义个 get_content 函数。这时 get_content 也是个对象,它能做所有对象的操作。

def get_content():  return 'hello world'

它有 id ,有 type ,有值。

>>> id(get_content)140090200473112>>> type(get_content)<class 'function'>>>> get_content<function get_content at 0x7f694aa2be18>

跟其他对象一样可以被赋值给其它变量。

>>> func_name = get_content>>> func_name()'hello world'

它可以当参数传递,也可以当返回值

>>> def foo(bar):...   print(bar())...   return bar...>>> func = foo(get_content)hello world>>> func()'hello world'

2. 自定义函数对象

我们可以用 class 来构造函数对象。有成员函数 __call__ 的就是函数对象了,函数对象被调用时正是调用的 __call__ 。

class FuncObj(object):  def __init__(self, name):    print('Initialize')    self.name= name  def __call__(self):    print('Hi', self.name)

我们来调用看看。可以看到, 函数对象的使用分两步:构造和调用 (同学们注意了,这是考点)。

>>> fo = FuncObj('python')Initialize>>> fo()Hi python

3. @ 是个语法糖

装饰器的 @ 没有做什么特别的事,不用它也可以实现一样的功能,只不过需要更多的代码。

@make_bolddef get_content():  return 'hello world'# 上面的代码等价于下面的def get_content():  return 'hello world'get_content = make_bold(get_content)

make_bold 是个函数,要求入参是函数对象,返回值是函数对象。 @ 的语法糖其实是省去了上面最后一行代码,使可读性更好。用了装饰器后,每次调用 get_content ,真正调用的是 make_bold 返回的函数对象。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表