分析掌握python装饰器(二)

作者: bd6b5cde5ce9 | 来源:发表于2017-12-18 21:38 被阅读25次

看完(一)后,想必已经对装饰器有了一个基本的概念。在(二)中,我将会对装饰器的一些高级用法做一点研究记录。

1、装饰器带其他参数

接着上面的例子,我们希望并不是每个人都有权限去使用这个计算函数,只有特定的人才可以。

  def checktype(personname=None):
    def decorate(func):
        def wrapper(*args,**kwargs):
            count = 0
            if personname == 'ghy':
                str = []
                for n in args:
                    if not isinstance(n,(int,float)):
                        log= '{}的类型无法计算'.format(n)
                        str.append(log)
                        count += 1
                if count == 0:
                    return func(*args,**kwargs)
                else:
                    print(str)
            else:
                print('{}, you are limited'.format(personname))
        return  wrapper
    return decorate

@checktype('test')
def calfunc(*numbers,sign=None):
    if sign is None:
        return 'please input a sign'
    if hasattr(case['+'], '__call__'):
        add=case['+']
        return print(add(*numbers))
#调用
calfunc('a','b',sign='+') #输出 test you  are limited

2、自定义装饰器属性

有时候我们会想通过为装饰器定义一些属性,来修改其中的参数
如上个例子所示,我们想通过属性来修改personname的值

from functools import wraps,partial
#将函数属性附加到包装函数上
#使用partial函数
#from functools import partial
#partial 函数的作用就是
#把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单。
#第一个参数为原函数。
def add_attr(obj,func=None):
    if func is None:
        return partial(add_attr,obj)
    setattr(obj,func.__name__,func)
    return func

#装饰器
def checktype(personname=None):
    def decorate(func):
        #保留原函数的一些元数据 比如 函数名 不加 calfunc.__name__输出 wrapper
        @wraps(func)
        def wrapper(*args,**kwargs):
            count = 0
            if personname == 'ghy':
                str = []
                for n in args:
                    if not isinstance(n,(int,float)):
                        log= '{}的类型无法计算'.format(n)
                        str.append(log)
                        count += 1
                if count == 0:
                    return func(*args,**kwargs)
                else:
                    print(str)
            else:
                print('{}, you are limited'.format(personname))

        @add_attr(wrapper) #相当于 add_attr(wrapper)()=>add_attr(wrapper,sef_modifypersonname)
        def sef_modifypersonname(newname):
            nonlocal personname  # 如果没有这个,下面一句是在当前作用域内又创建了一个personame
            personname = newname

        return  wrapper
    return decorate
@checktype('test')
def calfunc(*numbers,sign=None):
    if sign is None:
        return 'please input a sign'
    if hasattr(case['+'], '__call__'):
        add=case['+']
        return print(add(*numbers))

calfunc(1,2,sign='+') #输出 test you are limited
calfunc.sef_modifypersonname('ghy')
calfunc(1,2,sign='+') #输出 3

#装饰器解包,调用__wrapped__ 不进入装饰器包装函数
calfunc.sef_modifypersonname('test')
calfunc.__wrapped__(1,2,sign='+') #输出 3

上面一个比较重要的稍微难以理解的点就是@add_attr(wrapper),但其实你只要明白了

装饰器是在代码解释的时候就已经调用执行了

也就是说我们的装饰器处的代码,我们可以心里自动给它默认为

sef_modifypersonname=add_attr(wrapper)(sef_modifypersonname)

还有一个即 @wraps(func)注释已经写的很清楚了,保留原函数的元数据。

相关文章

  • 分析掌握python装饰器(二)

    看完(一)后,想必已经对装饰器有了一个基本的概念。在(二)中,我将会对装饰器的一些高级用法做一点研究记录。 1、装...

  • 分析掌握python装饰器(一)

    如果你学了一段时间Python,那么你一定听说过装饰器。 装饰器顾名思义,就是用来装饰函数的,给函数做一个漂亮的包...

  • [译] Python装饰器Part II:装饰器参数

    这是Python装饰器讲解的第二部分,上一篇:Python装饰器Part I:装饰器简介 回顾:不带参数的装饰器 ...

  • Python装饰器

    Python装饰器 一、函数装饰器 1.无参装饰器 示例:日志记录装饰器 2.带参装饰器 示例: 二、类装饰器 示例:

  • python 装饰器二

    昨天了解了python 装饰器的部分概念,今天继续昨天的内容稍作分析。首先还是来看一个装饰器 @符号是python...

  • 利用世界杯,读懂 Python 装饰器

    Python 装饰器是在面试过程高频被问到的问题,装饰器也是一个非常好用的特性, 熟练掌握装饰器会让你的编程思路更...

  • 利用世界杯,读懂 Python 装饰器

    Python 装饰器是在面试过程高频被问到的问题,装饰器也是一个非常好用的特性,熟练掌握装饰器会让你的编程思路更加...

  • 装饰器模式

    介绍 在python装饰器学习 这篇文章中,介绍了python 中的装饰器,python内置了对装饰器的支持。面向...

  • 我终于弄懂了Python的装饰器(四)

    此系列文档: 1. 我终于弄懂了Python的装饰器(一) 2. 我终于弄懂了Python的装饰器(二) 3. 我...

  • 我终于弄懂了Python的装饰器(二)

    此系列文档: 1. 我终于弄懂了Python的装饰器(一) 2. 我终于弄懂了Python的装饰器(二) 3. 我...

网友评论

    本文标题:分析掌握python装饰器(二)

    本文链接:https://www.haomeiwen.com/subject/zxdjwxtx.html