Python automated transport Koriyuki function advanced

Source: Internet
Author: User
Tags closure generator wrapper

1. Function nesting
Nested definition of a function: Within a function, another function is defined
Nested invocation of a function: in the process of invoking a function, another function is called
Code:

>>> def f1 (): ... def f2 ():.. print (' from F2 ') ... def f3 (): .... Print (' from F3 ') ...         . F3 () ... f2 () ...

Execution Result:

>>> F1 () from F2from F3

2, namespace and scope: the place where the name is stored, exactly the space of the relationship where the name is bound to the variable value
namespace classification: Built-in namespace, global namespace, and local namespace
    Built-in namespaces: The Python interpreter starts with some built-in names
    global namespaces: Names that are generated at file-level (Process Control statement definition, non-indented definition) definitions, and that are created at the time of file execution
     local name functions:
    Load Order: Built-in----> Global----> Local
    name lookup order: Local----> Global----> Built-in
Scopes: scope of Action
    scope classification: global scope and local scope
    global scope: Global survival, globally valid. View function globals (), display dictionary type
    local scope: temporary survival, local effect. View function locals (), display dictionary type
Keyword: global nonlocal
Local modification globally, for non-mutable types need to use global, mutable type does not need to use global
locally modified local, For non-mutable types you need to use nonlocal, the mutable type does not need to use nonlocal
Note: Try to avoid using local modify global
Focus: scope relationships, in function definitions, name lookups in functions are fixed and call location Independent. When calling a function, you must return to the location where the function was originally defined to find the scope relationship

x = 1def F1 (): Def f2 (): Print (x) # x is global scope return F2 () def foo (): x = + f1 () foo () x = 10foo ()

3. Closure function
Closures (Closure) are short for lexical closures (Lexical Closure) and are functions that reference free variables. This quoted free variable will exist with this function, even if it has left the environment in which it was created. So, there is another argument that closures are entities that are composed of functions and their associated reference environment.
Closures can be visually interpreted as a closed package, which is a function, and of course the corresponding logic within the function, where the contents of the package are free variables, and free variables can wander around the parcel. There must be a premise, of course, that the package was created.
As can be understood in Python, a closure is what I call a function A, and the function a returns a function B to me. The returned function, B, is called a closure. The argument that I pass when I call function A is a free variable.

1. Definition
Closures in Python are defined (interpreted) as: if, in an intrinsic function, a reference is made to a variable in an outer scope (but not at the global scope), the intrinsic function is considered a closure (closure). This definition is relatively straightforward, well understood, Unlike other definitions, the academic tastes are full (those who explain the meaning of a noun are filled with a bunch of other strange nouns that are not suitable for beginners). Here is a simple example to illustrate.

>>> def ADDX (x): ... def adder (y): return x + y ... return adder...>>> c = ADDX (8) >>> Typ E (c) <class ' function ' > >>> c.__name__ ' Adder ' >>> C (10) 18

This simple code and definition is used to illustrate closures: if in an intrinsic function: Adder (y) is the intrinsic function that references variables in the outer scope (but not at the global scope): X is the referenced variable, x is inside the outer scope addx, but not in the global scope, Then this intrinsic function adder is a closure.
Closure = function Block + environment when defining functions, Adder is the function block, X is the environment, of course, this environment can have many, more than a simple x. So, if you want to use a word to understand the closure function, that is: The function contains a child function, and finally return the child function.
2. Considerations for using closures
2.1 In closures, you cannot modify the local variables of the outer scope.

>>> def foo (): ... m = 0 ...         Def foo1 (): ... m = 1 ... Print (m) ... print (m) ... foo1 () ... print (m) ...>>> foo () 010

As can be seen from the execution result, although a variable m is defined in the closure, it does not change the local variable m in the outer function.

2.2 The following code is a classic error code when using closures in Python

>>> def foo (): ... a = 1 ...         def bar (): ... a = a + 1 ... Return a ... return bar ...

This procedure is intended to be done by incrementing the variable a every time the closure function is called. But in actual use

>>> c=foo () >>> print (c ()) Traceback (most recent call last): File "<stdin>", line 1, in <module > File "<stdin>", line 4, in barunboundlocalerror:local variable ' a ' referenced before assignment

This is because Python imports all of the closure function bar () to parse its local variables when executing code c=foo (), and the Python rule specifies that all variables on the left side of the assignment statement are local variables, and in the closure bar (), the variable A is on the left of the assignment symbol "=", is considered by Python to be a local variable in bar (). The next time you execute print C (), the program runs to a = a + 1 o'clock, because a has previously been attributed to a local variable in bar (), so Python will find the value of a in bar () to the right of the assignment statement, and the result will be an error if it is not found. The solution is simple.

def foo (): a = [1] def bar (): a[0] = a[0] + 1 return a[0] return bar

Just set a as a container. This is somewhat uncomfortable to use, so after python3, before a = a + 1, use the statement nonloacal A, which explicitly specifies that a is not a local variable of the closure.


4, the decorative device
1. An adorner is actually an executable function that takes a function as a parameter and returns a replacement function. Let's start from the simple, until we can write a practical decorator.
Closure principle: The extension is open, the modification is closed.

>>> def outer (some_func):...      def inner ():          print ("hello world!") ...          ret = some_func ()  # 1...          return ret + 1...      Return inner...>>> def foo ():...     return 1...>> > decorated = outer (foo)   #2 >>> decorated () hello world! 

Take a closer look at this decorator example. First, a function named outer with a single parameter some_func is defined. An inline function is then defined inside the outer inner.inner function prints a line of string and then calls Some_func and gets its return value at the #1. The value of Some_func may be different every time outer is called, but it will be called regardless of what function some_func is. Finally, inner returns the return value of Some_func () plus 1. As you can see at #2, when the return function that is assigned to decorated is called, it gets a line of text output and a return value of 2, not the return value of the expected call Foo of 1.

We can say that the variable decorated is a decorative version of Foo-that is, Foo plus something. In fact, if you write a practical decorator, you might want to replace Foo with a decorative version, so you can always get the Foo version of "Something Else". Without learning any new syntax, it's easy to do this by re-assigning the variable that contains the function:

>>> foo = outer (foo) >>> foo<function Outer.<locals>.inner at 0x000000f47f5cba60>

Now any call to Foo () will not get the original Foo, but the new adorner version! Do you understand? To write a more practical decorator.

2. Application of function Adorner @ symbol

import timedef timemer (func):    def  Wrapper (*args,**kwargs):         start = time.time ()          return=func ()         stop  = time.time ()         print ("run time is: %s"  %  (Stop-start)         return RETURN     return wrapper If you define a function, you can decorate the function with the  @  symbol as follows: @timemerdef  index ():     time.sleep (2)     print ("Welcome to index") index () 

It is important to note that this approach and the simple substitution of the return value of the index function to replace the original variable are no different--python just adding some syntax to make it look clearer.
Using adorners is simple! Although it is difficult to write a practical adorner like Staticmethod or Classmethod, it is only necessary to add the @ adorner name before the function!
3. *args and *kwargs
Above we have written a practical decorator, but it is hard-coded, only for a specific type of function--a function with two parameters. The intrinsic function checker receives two parameters and then continues to pass the arguments to the function in the closure. What if we want an adorner that can fit any function? Let's implement a decorator that adds a counter for each call to the decorated function, but does not change the decorated function. This means that the adorner must receive the invocation information of any function it decorates, and that any arguments passed to the adorner are passed to them when the functions are called.

Import Timedef Timemer (func): Def wrapper (*args,**kwargs): start = Time.time () return=func (*args,**kwargs ) stop = Time.time () print ("Run time is:%s"% (Stop-start)) return return return wrapper

If you define a function, you can decorate the function with the @ symbol, as follows:

@timemerdef index (name): Time.sleep (2) print ("Welcome%s to index"%name) index ("name")

Use both *args and *kwargs to make adorners more versatile

4. Non-parametric adorner

current_usr={"User": None}def auth (func):    info = {          "Xuanwei":  {"Password":  "123123",  "number": 0},          "Linglong":  {"Password":  "123123",  "number": 0}     }    def wrapper (*args,**kwargs):         if current_usr["User"]:             return func (*args, **kwargs)         else:             while True:                 username = input ("Please enter your user name:   ")                 if  username in info:                     password = input ("Please enter password: ")                      if info[username]["Number"] > 1:                          print ("%s  User received lock"  % username)                           exit ()                      if password == info[username]["Password"]:                          current_usr["User "] = username                         return = func (*args, **kwargs )                          return RETURN                     else:                          Print ("User password error")                          info[username]["Number"] += 1                 else:                     print ("%s  user does not exist"  % username)     return wrapper@authdef index1 ():     print ("welcome  To index1 ")     return 123def index2 ():     print (" Welcome to index1 ")     return 123index1 () Index2 ()

5. Parametric Adorner

Def auth (auth_type =  "Dict"):     def deco (func):         current_usr = {"User": none}         def wrapper (*args,**kwargs):             if current_usr["User"]:                 return func (*args, **kwargs)              else:                 if auth_type ==  "File":                     with open ("Db.txt",  "R",  encoding= "Utf-8")  as read_f:                 &Nbsp;       info = eval (Read_f.read ())                  else :                     info =  {                          "Xuanwei":  {"Password":  "123123",  "number":  0},                      }                 while true:                     username = input ("Please enter user name: ")                      if username in info:                          password = input ("Please enter password: ")                          if info[ username]["Number"] > 1:                             print ("%s   User closed lock " % username"                              exit ()                           if password == info[username]["Password"]:                              current_usr["User"] = username                              return = func (*args, **kwargs)                               return RETURN                         else:                              print ("User password error")                              info[username]["Number"] += 1                      else:                         print ("%s  user does not exist"  % username)          return wrapper    return deco@auth () Def index ():     print ("Welcome to index")     return 123index ()

5, iterator
    iteration: is a repeating process, and every repetition is based on the last result
    What is an iterator object
         has __iter__ and __next__ methods, and execution __iter__ get the benefits of
    iterator objects that are still iterators
        1. Provides a unified (non-dependent) iterative approach to
        2. The iterator itself, less memory than other data types, next () has only 1 values in memory
    disadvantages of the iterator object
        1. The value is not flexible. Can only go backwards, cannot be returned, no index value flexible
        2. Cannot predict the end of the value, that is, cannot predict the length
    Judging an iterator object with an iterator object
        from collections import Iterator
         determines whether an iterator object
        print (Isinstance (object, Iterator))

6, Generator: In the function memory contains the yield keyword, then the result of the function is the generator, and the generator is an iterator
Features of the keyword yield:
(1) The result of the packet function makes an iterator that encapsulates the __iter__,__next__ method in an elegant way
(2) The state of the function pause and resume operation is a yield saved
The difference between return and yield:
(1) Same function: can return value
(2) Different: Return can only be performed once

This article is from the "Hyun-dimensional" blog, please be sure to keep this source http://xuanwei.blog.51cto.com/11489734/1951593

Python automated transport Koriyuki function advanced

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.