Function Decorators and Closures

Posted neozheng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Function Decorators and Closures相关的知识,希望对你有一定的参考价值。

Function decorators let us "mark" functions in the source code to enhance their behavior in some way. This is powful stuff, but mastering it requires understanding closures.

Aside from their appliation in decorators, closures are also essential for effective asynchronous programming with callbacks, and for coding in a functional style whenever it makes sense.

 

1. Decorators 101

Example 7-1. A decorator usually replaces a function with a different one

"""
A decorator is a callable that takes another function as argument(the decorated function). The decorator may perform
some processing with the decorated function, and returns it or replaces it with another function or callable object.
"""

"""
Assuming an existing decorator named decorate, this code:
    @decorate
    def target():
        print(‘running target()‘)
        
Has the same effect as writing this:
    def target():
        print(‘running target()‘)
        
    target = decorate(target)

The end result is the same: at the end of either of these snippets, the target name does not necessarily refer to
the original target function, but to whatever function is returned by decorate(target).
"""


# This example show that the decorated function is replaced.


>>> def deco(func):
...     def inner():
...         print("running inner()")
...     return inner
...
>>> @deco
... def target():
...     print(running target())
...
>>> target()  # Invoking the decorated target actually runs inner.
running inner()
>>> target  # target is a new reference to inner.
<function deco.<locals>.inner at 0x1036259d8>


"""
Strictly speaking, decorators are just syntactic sugar. As we just saw, you can always simply call a decorator like any
regular callable, passing another functions.  Sometimes that is actually convenient, especially when doing 
metaprogramming --- changing program behavior at runtime.
"""

To Summarize:

# the first crucial fact about decorators is that they have the power to replace the decorated function with a different one. 
# the second crucial fact is that they are executed immediately when a module is loaded.

 

2. When Python Execute Decorators

A key feature of decorators is that they run right after the decorated function is defined. This is usually at import time. (i.e., when a module is loaded by Python).

Example 7-2. The ex7_2_registration.py module

registry = []


def register(func):
    print(running register(%s) % func)
    registry.append(func)
    return func     # Return func: we must return a function; here we return the same received as argument.


@register
def f1():
    print(running f1())


@register
def f2():
    print(running f2())


def f3():
    print(running f3())


def main():
    print(running main())
    print(registry-->, registry)
    f1()
    f2()
    f3()


if __name__ == __main__:
    main()  # main() is only invoked if ex7_2_registration.py runs as a script.


# The output of running ex7_2_registration.py as a script looks like this:
"""
NEO:ch7-function-decorators-closures zhenxink$ python3 ex7_2_registration.py 
running register(<function f1 at 0x103e61488>)
running register(<function f2 at 0x103e61598>)
running main()
registry--> [<function f1 at 0x103e61488>, <function f2 at 0x103e61598>]
running f1()
running f2()
running f3()
"""

"""
register runs (twice) before any other function in the module. When register is called, it receives as an argument the
function object being decorated -- for example, <function f1 at 0x103e61488> .
After the module is loaded, the registry holds references to the two decorated functions: f1 and f2. These functions,
as well as f3, are only executed when explicitly called by main.
"""


# If ex7_2_registration.py is imported(and not run as a script), the output is this:
"""
>>> import ex7_2_registration
running register(<function f1 at 0x1035619d8>)
running register(<function f2 at 0x103561a60>)
>>> ex7_2_registration.registry
[<function f1 at 0x1035619d8>, <function f2 at 0x103561a60>]
"""


"""
The main point of Example 7-2 is to emphasize that function decorators are executed as soon as the module is imported,
but the decorated functions only run when they are explicitly invoked. This highlights the difference between
import time and runtime. (导入时 和 运行时)
"""

# Considering how decorators are commonly employed in real code, Example 7-2 is unusual in two ways:
"""
1. The decorator function is defined in the same module as the decorated functions. A real decorator is usually defined
in one module and applied to functions in other modules.
2. The register decorator returns the same function passed as argument. In practice, most decorators define as inner
function and return it.
"""


"""
Even though the register decorator in Example 7-2 returns the decorated function unchanged, that technique is not 
useless. Similar decorators are used in many Python web frameworks to add functions to some central registry -- for
example, a registry mapping URL patterns to functions that generate HTTP response. Such registration decorators may
or may not change the decorated function.
"""

 

 

 

 

 

end ...

以上是关于Function Decorators and Closures的主要内容,如果未能解决你的问题,请参考以下文章

python 来自http://code.activestate.com/recipes/498245-lru-and-lfu-cache-decorators/

翻译:《实用的Python编程》07_04_Function_decorators

call lua function from c and called back to c

CodeForces841C. Leha and Function(Codeforces Round #429 (Div. 2))

CodeForces 840A - Leha and Function | Codeforces Round #429 (Div. 1)

read and write in C