此系列产品文档:

1. 我终于弄懂了Python的装饰器(一)

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

3. 我终于弄懂了Python的装饰器(三)

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

四、装饰器的用法

通用性装饰器(这里有一篇文档要填补)

如要制做通用性装饰器(不管主要参数怎样 ,您都能够将其运用于一切涵数或方式 ),则只需应用*args, **kwargs

def a_decorator_passing_arbitrary_arguments(function_to_decorate):
    #包裝器接纳一切主要参数(这些能够参照文档:       填补文档               )
    def a_wrapper_accepting_arbitrary_arguments(*args, **kwargs):
        print("Do I have args?:")
        print(args)
        print(kwargs)
        function_to_decorate(*args, **kwargs)
    return a_wrapper_accepting_arbitrary_arguments

@a_decorator_passing_arbitrary_arguments
def function_with_no_argument():
    print("Python is cool, no argument here.")

function_with_no_argument()
#输出:
#Do I have args?:
#()
#{}
#Python is cool, no argument here.

@a_decorator_passing_arbitrary_arguments
def function_with_arguments(a, b, c):
    print(a, b, c)

function_with_arguments(1,2,3)
#输出:
#Do I have args?:
#(1, 2, 3)
#{}
#1 2 3 

@a_decorator_passing_arbitrary_arguments
def function_with_named_arguments(a, b, c, platypus="Why not ?"):
    print("Do {0}, {1} and {2} like platypus? {3}".format(a, b, c, platypus))

function_with_named_arguments("Bill", "Linus", "Steve", platypus="Indeed!")
#输出:
#Do I have args ? :
#('Bill', 'Linus', 'Steve')
#{'platypus': 'Indeed!'}
#Do Bill, Linus and Steve like platypus? Indeed!

class Mary(object):

    def __init__(self):
        self.age = 31

    @a_decorator_passing_arbitrary_arguments
    def sayYourAge(self, lie=-3): # You can now add a default value
        print("I am {0}, what did you think?".format(self.age   lie))

m = Mary()
m.sayYourAge()
#输出:
# Do I have args?:
#(<__main__.Mary object at 0xb7d303ac>,)
#{}
#I am 28, what did you think?

最好作法:装饰器

留意:

  • 装饰器是在Python 2.4中引进的,因而请保证的编码将在> = 2.4上运作。
  • 装饰器使调用函数很慢 。(请记牢这一点)
  • 您不能取消装饰设计作用。(有一些方法 ,能够建立能够被删掉的装饰器,可是没人应用他们。)因而,一旦装饰设计了一个涵数 ,就对全部编码开展了装饰设计 。
  • 装饰器包裝涵数,这会使他们无法调节。(这在Python> = 2.5时有一定的调节;请参照以下几点。)

functools控制模块是在Python 2.5中引进的 。
它包含涵数functools.wraps(),该涵数将装饰后的涵数的名字 ,控制模块和文档字符串数组拷贝到其包裝器中。

(有意思的事是:functools.wraps()也是一个装饰器!)

#以便开展调节,stacktrace将向您显示信息涵数__name__
def foo():
    print("foo")

print(foo.__name__)
#输出: foo

#应用装饰器时,输出的信息内容会越来越杂乱,已不是foo	,只是wrapper
def bar(func):
    def wrapper():
        print("bar")
        return func()
    return wrapper

@bar
def foo():
    print("foo")

print(foo.__name__)
#输出: wrapper

# "functools" can help for that

import functools

def bar(func):
    # We say that "wrapper", is wrapping "func"
    # and the magic begins
    @functools.wraps(func)
    def wrapper():
        print("bar")
        return func()
    return wrapper

@bar
def foo():
    print("foo")

print(foo.__name__)
#outputs: foo

Python自身出示了一些装饰设计:property,staticmethod,等。

  • Django应用装饰器来管理方法缓存文件和查询管理权限 。
  • 仿冒的内联多线程调用函数 。

怎么使用链条式装饰器?

# 胆大的应用链条式装饰器吧
def makebold(fn):
    # The new function the decorator returns
    def wrapper():
        # Insertion of some code before and after
        return "<b>"   fn()   "</b>"
    return wrapper

# The decorator to make it italic
def makeitalic(fn):
    # The new function the decorator returns
    def wrapper():
        # Insertion of some code before and after
        return "<i>"   fn()   "</i>"
    return wrapper

@makebold
@makeitalic
def say():
    return "hello"

print(say())
#输出: <b><i>hello</i></b>

# This is the exact equivalent to 
def say():
    return "hello"
say = makebold(makeitalic(say))

print(say())
#输出: <b><i>hello</i></b>

如今 ,您能够临时学会放下高兴的情绪,大家来动动脑子,看一下装饰器的高級用法。


全文连接:https://stackoverflow.com/questions/739654/how-to-make-a-chain-of-function-decorators

文中先发于BigYoung华明镇

本文版权归趣快排营销www.SEOguruBLOG.com 所有,如有转发请注明来出,竞价开户托管,seo优化请联系QQ㊣61910465