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 ...

原文地址:https://www.cnblogs.com/neozheng/p/12254440.html

时间: 2024-10-22 14:36:43

Function Decorators and Closures的相关文章

python closure and function decorators 2

好吧,基础打好,聊聊decorator,先看这段代码: def SayHi(name): return "How are you {0}, good morning".format(name) def decoator(func): def func_wrapper(name): return "<p>{0}</p>".format(func(name)) return func_wrapper hi = decoator(SayHi) pr

python closure and function decorators 1

原文:http://thecodeship.com/patterns/guide-to-python-function-decorators/ 仅此做一个中文翻译: 我们知道,python在方法def的使用上,有一些非常强大的功能. 譬如,将方法传给一个变量: def sayHI(name): return "hi " + name ExexSayHI = sayHI print ExexSayHI("Allen") 或者在方法中定义方法 def SayHi(nam

JavaScript Decorators 的理解 和使用

Decorators,按字面理解就是装饰器的意思.装饰的意思,我想大家都明白,就是对一个物件进行美化,让它变得更漂亮.现实的例子就是房屋装修.你买了一套房子,但是毛坯房,你肯定不想住,那就对它装饰一下,床,桌子,电视,冰箱等一通买,房子变漂亮了,住的也舒心了,同时功能也强大了,因为我们可以看电视了,上网了. Js中,Decorators的作用也是如此,对一个类或者其属性方法进行装饰,让它功能更加强大.语法非常简单,就是在一个类或者其属性方法前面加上@decorator,decorator 指的是

闭包结构的本质

闭包定义: 如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包; 闭包的概念:闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数.这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外.所以,闭包是由函数和与其相关的引用环境组合而成的实体. 采用比较说法就是,通常一个函数运行结束之后,内部变量就会被销毁释放,C就是这样:然而在闭包这种结构中,外部函数的局部变量在该函数运行之后,其

TypeScript官方文档翻译-5

1.1 Ambient Declarations 1.1 环境声明 An ambient declaration introduces a variable into a TypeScript scope, but has zero impact on the emitted JavaScript program. Programmers can use ambient declarations to tell the TypeScript compiler that some other co

Angular 2 Pipe

Angular 2 Pipe Angular 2 中 Pipe(管道) 与 Angular 1.x 中的 filter(过滤器) 的作用的是一样的.它们都是用来对输入的数据进行处理,如大小写转换.数值和日期格式化等. Angular 2 内建管道 AsyncPipe.CurrencyPipe.DatePipe.DecimalPipe.I18nPluralPipe.I18nSelectPipe. JsonPipe.LowerCasePipe.PercentPipe.SlicePipe.TitleC

JAVASCRIPT的一些知识点梳理

春节闲点,可以安心的梳理一下以前不是很清楚的东东.. 看的是以下几个URL: http://web.jobbole.com/82520/ http://blog.csdn.net/luoweifu/article/details/41466537 http://javascriptissexy.com/understand-javascript-closures-with-ease/ http://javascriptissexy.com/javascript-variable-scope-an

[TypeScript] Reflection and Decorator Metadata

TypeScript allows you to emit decorator metadata which enables more powerful features through reflection. This lesson show you how decorators and reflection fit together and how to configure your own decorators to use reflection. For now, if we look

Python 函数装饰器入门

原文链接: --> A guide to Python's function decorators Python功能强劲,语法表现力强,尤其装饰器深深的吸引着我.在设计模式中,装饰器可以在不使用子类的情况下,动态的改变函数,方法以及类的功能.这个功能非常有用,特别在你想扩展函数的功能同时又不想改变原有的函数.的确,我们任意的实现装饰器设计模式,但是,python通过提供简单的语法和特性让装饰器的实现变的如此简单. 在本文中,我将用一组例子来深入浅入python 函数装饰器的功能,所有的例子都是在