前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python修饰器的特殊用法

python修饰器的特殊用法

作者头像
用户2936342
发布2018-08-27 14:29:27
9480
发布2018-08-27 14:29:27
举报
文章被收录于专栏:nummynummy

最基本的修饰器包括了无参数的修饰器和带参数的修饰器,这两种修饰器都是针对函数的,讲解的博客已经很多了,就不再赘述了,这里重点讲下修饰器的几种特殊用法。

使用类创建修饰器

因为类也是可以callable的,只要实现__call__魔法函数即可,所以类也可以实现修饰器效果。

代码语言:javascript
复制
import functools

class Debug(object):
    def __init__(self, function):
        self.function = function
        functools.update_wrapper(self, function)

    def __call__(self, *args, **kwargs):
        output = self.function(*args, **kwargs)
        print('%s(%r, %r): %r' % (self.function.__name__, args, kwargs, output))
        return output

@Debug
def spam(eggs):
    return "spam" * (eggs%5)

spam(3)

结果如下所示:

代码语言:javascript
复制
spam((3,), {}): 'spamspamspam'

使用类创建修饰器和使用函数创建修饰器的区别是,后者使用 functools.wraps,前者使用 functools.update_wrapper

修饰类的方法

修饰类的方法与修饰函数形式差不多,唯一需要注意的是类方法中必须提供第一个变量self

代码语言:javascript
复制
import functools

def plus_one(function):
    @functools.wraps(function)
    def _plus_one(self, n):
        return function(self, n+1)
    return _plus_one

class Spam(object):
    @plus_one
    def get_eggs(self, n):
        return n*"eggs"

spam = Spam()
print(spam.get_eggs(2))

结果如下所示:

代码语言:javascript
复制
eggseggseggs

classmethodstaticmethodproperty描述器本质上都是类方法修饰器。classmethodstaticmethod的区别是classmethod只需要传递类对象,staticmethod既不用传递类对象也不用传递类的实例。

首先看下classmethodstaticmethod的用法

代码语言:javascript
复制
import pprint

class Spam(object):
    def some_instancemethod(self, *args, **kwargs):
        print("self: %r" % self)
        print("args: %s" % pprint.pformat(args))
        print("kwargs: %s" % pprint.pformat(kwargs))

    @classmethod
    def some_classmethod(cls, *args, **kwargs):
        print("cls: %r" % cls)
        print("args: %s" % pprint.pformat(args))
        print("kwargs: %s" % pprint.pformat(kwargs))

    @staticmethod
    def some_staticmethod(*args, **kwargs):
        print("args: %s" % pprint.pformat(args))
        print("kwargs: %s" % pprint.pformat(kwargs))


spam = Spam()
spam.some_instancemethod(1,2, a=3, b=4)
Spam.some_classmethod()
spam.some_classmethod()
Spam.some_classmethod(1,2, a=3,b=4)
Spam.some_staticmethod()
Spam.some_staticmethod(1,2,a=3,b=4)

结果如下所示:

代码语言:javascript
复制
self: <__main__.Spam object at 0x000001AF5FF335F8>
args: (1, 2)
kwargs: {'a': 3, 'b': 4}
cls: <class '__main__.Spam'>
args: ()
kwargs: {}
cls: <class '__main__.Spam'>
args: ()
kwargs: {}
cls: <class '__main__.Spam'>
args: (1, 2)
kwargs: {'a': 3, 'b': 4}
args: ()
kwargs: {}
args: (1, 2)
kwargs: {'a': 3, 'b': 4}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018.07.30 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 使用类创建修饰器
  • 修饰类的方法
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档