Summary of some tips for advanced programming in Python

伊谢尔伦
Release: 2017-06-28 13:29:40
Original
1420 people have browsed it

This article mainly introduces some advanced programming skills in Python, including important advanced knowledge points such as tutors and decorators. They are all necessary basic skills for in-depth learning of Python development. You need Friends can refer to the following

Text:

This article shows some advanced Python design structures and how to use them. In daily work, you can choose the appropriate data structure according to your needs, such as requirements for fast searchability, requirements for data consistency, or requirements for indexes. You can also combine various data structures appropriately. , thereby generating a logical and easy-to-understand data model. Python's data structures are syntactically very intuitive and provide a large number of optional operations. This guide attempts to put together most of the commonly used data structure knowledge and provide a discussion of their best usage.
Comprehensions

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

A list comprehension contains the following parts:

  • An input sequence

  • A variable representing the members of the input sequence

  • An optional assertion expression

  • An output expression that converts members of the input sequence that satisfy the assertion expression into members of the output list Formula

For example, we need to generate a new sequence from an input list by squaring all integers greater than 0. You might write this:

num = [1, 4, -5, 10, -7, 2, 3, -1]
filtered_and_squared = []
 
for number in num:
 if number > 0:
 filtered_and_squared.append(number ** 2)
print filtered_and_squared
 
# [1, 16, 100, 4, 9]
Copy after login

Very simple, right? But this would be 4 lines of code, two levels of nesting and a completely unnecessary append operation. If you use filter, lambda and map functions, the code can be greatly simplified:

num = [1, 4, -5, 10, -7, 2, 3, -1]
filtered_and_squared = map(lambda x: x ** 2, filter(lambda x: x > 0, num))
print filtered_and_squared
 
# [1, 16, 100, 4, 9]
Copy after login

Well, in this way the code will expand in the horizontal direction. So can we continue to simplify the code? List derivation can give us the answer:

num = [1, 4, -5, 10, -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]
Copy after login
  • Iterator (iterator) traverses each member of the input sequence num x

  • Assertion type Determine whether each member is greater than zero

  • If the member is greater than zero, it is given to the output expression and becomes a member of the output list after being squared.

The list comprehension is encapsulated in a list, so obviously it can generate a new list immediately. There is only a type function call and no implicit call to the lambda function. The list comprehension uses a regular iterator, an expression, and an if expression to control the optional parameters.

On the other hand, list derivation may also have some negative effects, that is, the entire list must be loaded into memory at once. This is not a problem for the example given above, even after it is expanded several times. None of it is a problem. But the limit will always be reached and the memory will always be used up.

In response to the above problems, Generator (Generator) can solve it very well. The generator expression does not load the entire list into memory at one time, but generates a generatorobject(Generator objector), so only one list element is loaded at a time.

Generator expressions have almost the same syntax structure as list comprehensions. The difference is that generator expressions are surrounded by parentheses instead of square brackets:

num = [1, 4, -5, 10, -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
Copy after login

This is better than List comprehension efficiency is slightly improved, let us transform the code again:

num = [1, 4, -5, 10, -7, 2, 3, -1]
 
def square_generator(optional_parameter):
 return (x ** 2 for x in num if x > optional_parameter)
 
print square_generator(0)
# <generator object <genexpr> at 0x004E6418>
 
# Option I
for k in square_generator(0):
 print k
# 1, 16, 100, 4, 9
 
# Option II
g = list(square_generator(0))
print g
# [1, 16, 100, 4, 9]
Copy after login

Unless there are special reasons, generator expressions should always be used in the code. But unless you are dealing with very large lists, you won't see a significant difference.

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

alist = [&#39;a1&#39;, &#39;a2&#39;, &#39;a3&#39;]
blist = [&#39;1&#39;, &#39;2&#39;, &#39;3&#39;]
 
for a, b in zip(alist, blist):
 print a, b
 
# a1 1
# a2 2
# a3 3
Copy after login

Let’s look at a two-stage list derivation Example of traversing directory :

import os
def tree(top):
 for path, names, fnames in os.walk(top):
 for fname in fnames:
  yield os.path.join(path, fname)
 
for name in tree(&#39;C:\Users\XXX\Downloads\Test&#39;):
 print name
Copy after login

Decorators

Decorators provide us with a function to add existing functions or classes effective method. Does it sound a lot like the concept of aspect-oriented programming (Aspect-Oriented Programming) in Java? Both are simple, and decorators are more powerful. For example, if you want to perform some special operations (such as some security, tracking, locking, etc.) at the entry and exit points of a function, you can use decorators.

A decorator is a special function that wraps another function: the main function is called and its return value is passed to the decorator, which then returns a replacement function that wraps the main function , what other parts of the program see will be this wrapper function.

def timethis(func):
 &#39;&#39;&#39;
 Decorator that reports the execution time.
 &#39;&#39;&#39;
 pass
 
@timethis
def countdown(n):
 while n > 0:
 n -= 1
Copy after login

Syntactic sugar@ identifies the decorator.

好了,让我们回到刚才的例子。我们将用装饰器做一些更典型的操作:

import time
from functools import wraps
 
def timethis(func):
 &#39;&#39;&#39;
 Decorator that reports the execution time.
 &#39;&#39;&#39;
 @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
 
@timethis
def countdown(n):
 while n > 0:
 n -= 1
 
countdown(100000)
 
# (&#39;countdown&#39;, 0.006999969482421875)
Copy after login

当你写下如下代码时:

@timethis
def countdown(n):
Copy after login

意味着你分开执行了以下步骤:

def countdown(n):
...
countdown = timethis(countdown)
Copy after login

装饰器函数中的代码创建了一个新的函数(正如此例中的wrapper函数),它用 *args 和 **kwargs 接收任意的输入参数,并且在此函数内调用原函数并且返回其结果。你可以根据自己的需要放置任何额外的代码(例如本例中的计时操作),新创建的包装函数将作为结果返回并取代原函数。

@decorator
def function():
 print("inside function")
Copy after login

当编译器查看以上代码时,function()函数将会被编译,并且函数返回对象将会被传给装饰器代码,装饰器将会在做完相关操作之后用一个新的函数对象代替原函数。

装饰器代码是什么样的?大部分的例子都是将装饰器定义为函数,而我发觉将装饰器定义成类更容易理解其功能,并且这样更能发挥装饰器机制的威力。

对装饰器的类实现唯一要求是它必须能如函数一般使用,也就是说它必须是可调用的。所以,如果想这么做这个类必须实现call方法。

这样的装饰器应该用来做些什么?它可以做任何事,但通常它用在当你想在一些特殊的地方使用原函数时,但这不是必须的,例如:

class decorator(object):
 
 def init(self, f):
 print("inside decorator.init()")
 f() # Prove that function definition has completed
 
 def call(self):
 print("inside decorator.call()")
 
@decorator
def function():
 print("inside function()")
 
print("Finished decorating function()")
 
function()
 
# inside decorator.init()
# inside function()
# Finished decorating function()
# inside decorator.call()
Copy after login

The above is the detailed content of Summary of some tips for advanced programming in Python. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template