python迭代器生成器和装饰器变得容易

Recently I received an email from one of my readers asking me to write about Python’s complex topics such as Iterators, Generators, and Decorators. In this post, I’m going to cover the basics, implementation, and how to use them in your code.

最近,我从一位读者那里收到一封电子邮件,要求我写关于Python的复杂主题,例如迭代器,生成器和装饰器。 在这篇文章中,我将介绍基础知识,实现以及如何在代码中使用它们。

迭代器 (Iterators)

An iterator is an object that can be iterated upon which means that you can traverse through all the values. List, tuples, dictionaries, and sets are all iterable objects.

迭代器是可以对其进行迭代的对象,这意味着您可以遍历所有值。 列表,元组,字典和集合都是可迭代的对象。

To create an object as an iterator you have to implement the methods __iter__() and __next__() to your object where —

要将对象创建为迭代器,必须对对象实现__iter__()__next__() ,其中—

__iter__() returns the iterator object itself. This is used in for and in statements.

__iter __()返回迭代器对象本身。 这用于forin语句。

__next__() method returns the next value in the sequence. In order to avoid the iteration to go on forever, raise the StopIteration exception.

__next __()方法返回序列中的下一个值。 为了避免迭代永远进行,请引发StopIteration异常。

For the implementation, I wrote a simple code:

对于实现,我编写了一个简单的代码:

class example_range:
def __init__(self, n):
self.i = 4
self.n = ndef __iter__(self):
return selfdef __next__(self):
if self.i < self.n:
i = self.i
self.i += 1
return i
else:
raise StopIteration()

Output:

输出:

n= example_range(10)
list(n)Output--[4, 5, 6, 7, 8, 9]

You can use this in your code. For example like:

您可以在代码中使用它。 例如:

n= example_range(15)
for i in n :
print (i, end=',')

Output:

输出:

4,5,6,7,8,9,10,11,12,13,14

As compared to for loop above:

与上面的for循环相比:

iterator = iter(n)
while True:
try:
x = iterator.__next__()
print(x, end=',')
except StopIteration as e:
break

Output:

输出:

4,5,6,7,8,9,10,11,12,13,14

Why use iterators?

为什么要使用迭代器?

Iterators allow us to create and work with lazy iterable which means you can use an iterator for the lazy evaluation. This allows you to get the next element in the list without re-calculating all of the previous elements. Iterators can save us a lot of memory and CPU time.

迭代器使我们可以创建和处理惰性迭代,这意味着您可以将迭代器用于惰性评估。 这使您可以获取列表中的下一个元素,而无需重新计算所有先前的元素。 迭代器可以为我们节省大量内存和CPU时间。

Python has many built-in classes that are iterators, e.g — enumerate, map ,filer , zipand reversed etc. objects are iterators.

Python具有许多内置的迭代器类,例如— enumeratemapfilerzipreversed等。对象是迭代器。

发电机 (Generators)

Generator functions act just like regular functions with just one difference that they use the Python yieldkeyword instead of return . A generator function is a function that returns an iterator. A generator expression is an expression that returns an iterator. Generator objects are used either by calling the next method on the generator object or using the generator object in a “for in” loop.

生成器函数的行为就像常规函数一样,只是区别在于它们使用Python yield关键字而不是return 。 生成器函数是返回迭代器的函数。 生成器表达式是一个返回迭代器的表达式。 通过在生成器对象上调用next方法或在“ for in”循环中使用生成器对象来使用生成器对象。

Code:

码:

def test_sequence():
num = 0
while num<10:
yield num
num += 1
for i in test_sequence():
print(i, end=",")

Output:

输出:

0,1,2,3,4,5,6,7,8,9

A return statement terminates a function entirely but a yield statement pauses the function saving all its states and later continues from there on successive calls.

return语句完全终止一个函数,但是yield语句暂停该函数并保存所有状态,然后在后续调用中从那里继续。

带有循环的Python生成器 (Python Generators with a Loop)

#Reverse a string
def reverse_str(test_str):
length = len(test_str)
for i in range(length - 1, -1, -1):
yield test_str[i]for char in reverse_str("Trojan"):
print(char,end =" ")

Output:

输出:

n a j o r T

生成器表达式 (Generator Expression)

Generator expressions can be used as the function arguments. Just like list comprehensions, generator expressions allow you to quickly create a generator object within minutes with just a few lines of code.

生成器表达式可以用作函数参数。 就像列表推导一样,生成器表达式使您可以在几分钟内用几行代码快速创建生成器对象。

Code:

码:

# Initialize the list
test_list = [1, 3, 6, 10]# list comprehension
list_comprehension = [x**3 for x in test_list]# generator expression
test_generator = (x**3 for x in test_list)print(list_)
print(type(test_generator))
print(tuple(test_generator))

Output:

输出:

[1, 9, 36, 100]
<class 'generator'>
(1, 27, 216, 1000)

The major difference between a list comprehension and a generator expression is that a list comprehension produces the entire list while the generator expression produces one item at a time as lazy evaluation. For this reason, compared to a list comprehension, a generator expression is much more memory efficient that can be understood from profiling code below —

列表理解和生成器表达式之间的主要区别在于,列表理解生成整个列表,而生成器表达式一次生成一个项作为惰性求值。 因此,与列表理解相比,生成器表达式具有更高的内存效率,可以从下面的性能分析代码中了解它们-

import sys
cubed_list = [i ** 3 for i in range(10000)]
print("List comprehension size(bytes):", sys.getsizeof(cubed_list))cubed_generator = (i ** 3 for i in range(10000))
print("Generator Expression object(bytes):", sys.getsizeof(cubed_generator))

Output:

输出:

List comprehension size(bytes): 87624
Generator Expression object(bytes): 120

When we run the profiling:

当我们运行分析时:

import cProfile as profiling 
#list comprehension profiling
profiling.run('sum([i ** 3 for i in range(10000)])')
#Generator Expression profiling
profiling.run('sum((i ** 3 for i in range(10000)))')

Output:

输出:

5 function calls in 0.004 seconds   Ordered by: standard name   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
1 0.004 0.004 0.004 0.004 <string>:1(<listcomp>)
1 0.000 0.000 0.004 0.004 <string>:1(<module>)
1 0.000 0.000 0.004 0.004 {built-in method builtins.exec}
1 0.000 0.000 0.000 0.000 {built-in method builtins.sum}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
10005 function calls in 0.014 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function)
10001 0.012 0.000 0.012 0.000 <string>:1(<genexpr>)
1 0.000 0.000 0.014 0.014 <string>:1(<module>)
1 0.000 0.000 0.014 0.014 {built-in method builtins.exec}
1 0.002 0.002 0.014 0.014 {built-in method builtins.sum}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}

装饰器 (Decorator)

A decorator in Python is any callable Python object that is used to modify a function or a class. It takes in a function, adds some functionality, and returns it. Decorators are a very powerful and useful tool in Python since it allows programmers to modify/control the behavior of function or class. Decorators are usually called before the definition of a function you want to decorate. There are two different kinds of decorators in Python:

Python中的装饰器是用于修改函数或类的任何可调用Python对象。 它接受一个函数,添加一些功能,然后返回它。 装饰器是Python中非常强大且有用的工具,因为它允许程序员修改/控制函数或类的行为。 通常在要装饰的函数的定义之前调用装饰器。 Python中有两种不同的装饰器:

  • Function decorators

    功能装饰器
  • Class decorators

    类装饰器

Code:

码:

def test_decorator(func):
def function_wrapper(x):
print("Before calling " + func.__name__)
res = func(x)
print(res)
print("After calling " + func.__name__)
return function_wrapper@test_decorator
def sqr(n):
return n ** 2sqr(54)

Output:

输出:

Before calling sqr
2916
After calling sqr

多个装饰器实现单个功能 (Multiple Decorators to a Single Function)

When using Multiple Decorators to a single function, the decorators will be applied in the order they’ve been called.

当对一个函数使用多个Decorator时,装饰器将按照被调用的顺序应用。

Code:

码:

def lowercase_decorator(function):
def wrapper():
func = function()
make_lowercase = func.lower()
return make_lowercasereturn wrapperdef split_string(function):
def wrapper():
func = function()
split_string = func.split()
return split_stringreturn wrapper
@split_string
@lowercase_decorator
def test_func():
return 'MOTHER OF DRAGONS'
test_func()

Output:

输出:

['mother', 'of', 'dragons']

You can also pass the arguments to the wrapper function.

您还可以将参数传递给包装函数。

Thanks for reading. Keep Learning :)

谢谢阅读。 保持学习 :)

普通英语的Python (Python In Plain English)

Did you know that we have three publications and a YouTube channel? Find links to everything at plainenglish.io!

您知道我们有三个出版物和一个YouTube频道吗? 在plainenglish.io上找到所有内容的链接!

翻译自: https://medium.com/python-in-plain-english/python-iterators-generators-and-decorators-made-easy-659cae26054f

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值