Learn About Python Decorators

  • nested function

在探讨python的装饰器模式之前,我们需要先了解一下nested function,在java中我们会使用内部类,来实现访问权限控制和类的隔离,在python中进一步深入到函数级别,看一个例子:

def parent():
    print 'parent function'
    
    def first_child():
        print 'this is the first child'

    def second_child():
        print 'this is the second child'

    first_child()
    second_child()

if __name__ == '__main__':
    parent()

在这个例子中,我们call了函数parent(),其中的调用逻辑对外部调用者是不可见的,这就意味着我们是无法调用first_child(), second_child()的。

  • returning functions

另一个需要了解的是python是可以返回函数,因此我们在get这个返回值时,应该以函数的方式去二次调用。

#!/usr/bin/env python
# encoding: utf-8

def parent():
    
    def first_child():
        print 'this is the first child'

    def second_child():
        print 'this is the second child'

    # focus that it does not return first_child(), leave call authorities callers
    return first_child
    

accept = parent()
accept()

我们结合前两点,再看一个例子:

#!/usr/bin/env python
# encoding: utf-8

def my_decorator(some_function):
    def wrapper():
        print("Before calling")
        some_function()
        print("After calling")
        
    return wrapper

def some_function_calling():
    print ('You are calling some_function_calling')

my_decorator(some_function_calling)()
  • Learn about @ symbol
#!/usr/bin/env python
# encoding: utf-8

def my_decorator(some_function):
    def wrapper():
        print 'Before some_function calling'
        some_function()
        print 'After some_function calling'
        
    return wrapper

@my_decorator
def some_function_calling():
    print 'You are calling some_function_calling()'

if __name__ == '__main__':
    some_function_calling()

some_function_calling()的函数名被注解的装饰器my_decorator获取,在调用some_function_calling等价于获取my_decorator结果,以实例run: 则是some_function_calling()
为保留被装饰函数的基本属性,常会使用@wraps注解,可以参见这个解释: http://stackoverflow.com/questions/308999/what-does-functools-wraps-do

Refer to:

https://realpython.com/blog/python/primer-on-python-decorators/

 

 

 

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>