Advanced programming in Python a few tips summary

Source: Internet
Author: User
This article mainly introduces some of the advanced programming techniques in Python, including the important advance knowledge points such as derivations and decorators, all of which are essential basic skills for in-depth learning of Python development, and the need for a friend to refer to

Body:

This article shows some of the advanced Python design structures and how they are used. In your daily work, you can choose the right data structure for your needs, such as requirements for fast lookups, requirements for consistency of data, or requirements for indexes, as well as the appropriate combination of data structures to produce a logical and understandable data model. Python's data structure clauses are very intuitive and provide a number of optional operations. This guide attempts to put together most of the commonly used data structure knowledge and provides a discussion of its best use.
Derivation formula (comprehensions)

If you've been using Python for a long time, you should at least have heard of list comprehensions. This is a way to put a for loop, if expression, and an assignment statement into a single statement. In other words, you can use an expression to map or filter a list.

A list deduction consists of the following sections:

    • An input sequence

    • A variable that represents the input sequence member

    • An optional assertion expression

    • An output expression that transforms a member of an input sequence that satisfies an assertion expression into an output list member

For example, we need to generate a new sequence from an input list of all integer squares greater than 0, which you might write:

num = [1, 4, -5, ten,-7, 2, 3, -1]filtered_and_squared = [] for number in Num:if number > 0:filtered_and_squared.appe ND (number * * 2) Print filtered_and_squared # [1, 16, 100, 4, 9]

It's simple, isn't it? But this will have 4 lines of code, two layers of nesting plus a completely unnecessary append operation. If you use the filter, lambda, and map functions, you can greatly simplify your code:

num = [1, 4, -5, ten,-7, 2, 3, -1]filtered_and_squared = map (Lambda x:x * * 2, filter (lambda x:x > 0, num)) Print Filte red_and_squared # [1, 16, 100, 4, 9]

Well, that way the code will expand horizontally. So is it possible to continue simplifying the code? The list derivation can give us the answer:

num = [1, 4, -5, ten,-7, 2, 3, -1]filtered_and_squared = [x**2 for x in num if x > 0]print filtered_and_squared # [1, 16, 100, 4, 9]
    • Iterator (iterator) iterates through the input sequence for each member of Num x

    • Assertion determines whether each member is greater than 0

    • If the member is greater than 0, the output expression is given, and the square becomes a member of the output list.

The list derivation is encapsulated in a list, so it is obvious that it can generate a new list immediately. There is only one type function call and no implicit invocation of the lambda function, and the list derivation uses a regular iterator, an expression, and an if expression to control the optional arguments.

On the other hand, the list derivation may have some negative effects, that is, the entire list must be loaded in memory at once, which is not a problem for the example above, and even after several times the expansion is not a problem. But the limit is always reached and memory is always exhausted.

For the above problem, the generator (Generator) can be solved very well. The generator expression does not load the entire list into memory at one time, but instead generates a generator object (Generator objector), so only one list element is loaded at a time.

The builder expression has an almost identical syntax structure to the list derivation, except that the generator expression is surrounded by parentheses, not square brackets:

num = [1, 4, -5, ten,-7, 2, 3, -1]filtered_and_squared = (x**2 for x in num if x > 0) Print filtered_and_squared # < ; generator object <genexpr> at 0x00583e18> for item in Filtered_and_squared:print Item # 1, 16, 100 4,9

This is slightly more efficient than the list derivation, so let's change the code once again:

num = [1, 4, -5, ten,-7, 2, 3,-1] def square_generator (optional_parameter): Return (x * * 2 for x in num if x > Optiona L_parameter) Print Square_generator (0) # <generator object <genexpr> at 0x004e6418> # Option IFOR K in Square_g Enerator (0): Print k# 1, +, 4, 9 # Option IIg = list (square_generator (0)) print g# [1, 16, 100, 4, 9]

You should always use a generator expression in your code, unless you have a particular reason. But unless you are facing a very large list, you will not see the obvious difference.

The following example uses the Zip () function to process elements from two or more lists at once:

alist = [' A1 ', ' A2 ', ' A3 ']blist = [' 1 ', ' 2 ', ' 3 '] for a, b in zip (Alist, blist): Print A, B # a1 # A2 C A3 3

Let's look at an example of a two-order list-derived traversal directory:

Import osdef tree (top): For path, names, Fnames in Os.walk (top): For fname in fnames:  yield os.path.join (path, fname) For name in tree (' C:\Users\XXX\Downloads\Test '): Print name

Adorner (decorators)

Adorners provide us with an effective way to increase the functionality of existing functions or classes. Does that sound like the concept of aspect-oriented programming (Aspect-oriented programming) in Java? Both are simple, and the adorner has a more powerful function. For example, suppose you want to do something special with the entry and exit points of a function (such as some security, tracking, and locking operations), you can use adorners.

An adorner is a special function that wraps another function: The main function is called, and its return value is passed to the adorner, and the adorner returns an alternate function that wraps the main function, and the other part of the program sees the wrapper function.

def timethis (func): ' Decorator that reports the execution time. "Pass @timethisdef Countdown (n): While n > 0:n-= 1

The grammatical sugar @ identifies the adorner.

OK, let's go back to the example we just made. We will do some more typical operations with adorners:

Import timefrom functools Import Wraps def timethis (func): ' Decorator that reports the execution time. "@wraps (func) def wrapper (*args, **kwargs): start = time.time () result = Func (*args, **kwargs) end = Time.time () print ( Func.name, End-start) return result return wrapper @timethisdef Countdown (n): While n > 0:n-= 1 Countdown (100000) # ( ' Countdown ', 0.006999969482421875)

When you write the following code:

@timethisdef countdown (N):

means that you performed the following steps separately:

def countdown (n): ... countdown = Timethis (Countdown)

The code in the adorner function creates a new function (as in this example, the wrapper function), which receives arbitrary input parameters with *args and **kwargs, and calls the original function within the function and returns its result. You can place any extra code (such as the timing action in this example) according to your needs, and the newly created wrapper function will return as a result and replace the original function.

@decoratordef function (): print ("Inside function")

When the compiler looks at the above code, the function () function will be compiled and the return object will be passed to the adorner code, and the adorner will replace the original function with a new function object after the relevant operation has been completed.

What is the adorner code like? Most of the examples are defining adorners as functions, and I find it easier to understand the functionality of the adorner by defining it as a class, and this will give you more power over the adorner mechanism.

The only requirement for the class implementation of the adorner is that it must be able to be used as a function, meaning it must be callable. So, if you want to do this, the class must implement the call method.

What should such adorners be used for? It can do anything, but usually it is used when you want to use the original function in some special place, but this is not necessary, for example:

class Decorator (object): Def init (self, f): Print ("Inside Decorator.init ()") f () # Prove that func tion definition have completed def call (self): print ("Inside Decorator.call ()") @decoratordef function (): Print ("Inside Fu Nction () ") print (" Finished decorating function () ") function () # inside Decorator.init () # inside function () # finished Deco Rating function () # inside Decorator.call () 
Related Article

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.