Python Closures and decorators

Source: Internet
Author: User

Functions as objects and closures

The functions in Python are that first-class objects they can be passed as parameters to other functions, can be stored in data structures, or can be used as return values for functions

A simple example

# Foo.pydef CALLF (func):    return func ()
>>> import foo>>> def hello (): ...     Return ' Hello '    ... >>> f = foo.callf (Hello) # function as an arg>>> f ' hello '

Make a little change to the above code:

# Foo.pyx = 42def Callf (func):    return func ()
>>> import foo>>> x = 37>>> def hello (): ...     Return ' Hello. X is%d '% x...>>> foo.callf (hello) ' Hello. X is 37 '

Here we call FOO.CALLF (), but the value of x is not the value of the variable defined in foo.py, but the value before the function is called. Therefore, we should pay attention to the relationship between a function and the surrounding variables, there is the concept of closure closure

closure: When a function's statement is packaged with the environment they are executing, it becomes the so-called closure we can look at the properties of a function __globals__ , such as:

>>> hello.__globals__{' __builtins__ ': <module ' __builtin__ ' (built-in);, ' HelloWorld ': <function HelloWorld at 0x7bb30>, ' x ': Notoginseng, ' __name__ ': ' __main__ ', ' __doc__ ': None ' foo ': <module ' foo ' from ' foo.py ';}

You can see that Hello is already bound to x=37.

When using nested functions, closures give you inner function the environment to capture the execution needs, such as

Import Foodef Bar ():    x =    def helloworld ():        return "Hello world." X is%d "% x    foo.callf (HelloWorld) # returns ' Hello world, X is 13 '

Here the intrinsic function HelloWorld and x=13 have formed a closure

How can closures be used? Let's look at an example of a delay assignment:

From Urllib import urlopendef page (URL):    def get ():        return Urlopen (URL). Read ()    return get
>>> python = page ("http://www.python.org") >>> python<function get at 0x95d5f0>>>> Pydata = Python () # fetch http://www.python.org>>> pydata.__closure__ (<cell at 0x67f50:str object at 0x69230& gt;,) >>> python._ _closure_ _[0].cell_contents ' http://www.python.org '

The Pydata object is bound to the value of the parameter URL when it is assigned, and can be reserved for later invocation

Decorators

The function of the decorator decorator is to encapsulate other functions or classes inside, denoted by the @, eg:

@tracedef Square (x):    return x*x

Equivalent to

def Square (x):    return x*xsquare = Trace (square)

This example defines a square () function, but immediately passes it as a parameter to the trace () and replaces the returned object with the original square. Adorners as the name implies is to add some decorations to the original function, for example, we here the trace function can do some extra things, the last object returned can be a function containing square, that is, our square function "decorate"

Let's look at an example of the usual use:

enable_tracing = Trueif enable_tracing:    debug_log = open ("Debug.log", "W") def Trace (func):    if enable_tracing:        def CALLF (*args,**kwargs):            debug_log.write ("Calling%s:%s,%s\n"% (func._ _name_ _, args, Kwargs))            r = Func (*args,**kwargs)            Debug_log.write ("%s returned%s\n"% (func._ _name, R))            return R        return CALLF    else:        return func

This code can trace the call of the square function above, if enable_tracing, then use the function CALLF to encapsulate the Func, add the logging function inside, and CALLF finally return the Func function, That is, if we allow tracing, we will decorate the original function object as a tracking function object return, if not allow tracing, simply return to the Func itself, this is a very subtle design of the CALLF

Python Closures and decorators

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.