Pythonの - >(11)研究ノート

イテレータ、発電機、デコレータ

  • イテレータ
  • ジェネレータ
  • ジェネレータ式
  • クロージャ
  • デコレーター

イテレータ

イテレーションは、Pythonの最も強力な機能の一つはコレクション要素にアクセスする方法です。イテレータオブジェクトがトラバース位置であることを覚えていることができます。
イテレータオブジェクトは、すべての要素が、セッションが終わってアクセスされるまで、コレクションの最初の要素からの訪問を始めました。イテレータは、前方、後方ではない移動することができます。

イテレータを作成:

2つのメソッドを実装する必要性などのクラスを使用することは、イテレータ(クラスがクラスとしてコンストラクタ、Pythonのコンストラクタを有し__init__()、それが初期化を実行する際に、オブジェクト。) __iter__()イテレータオブジェクト自体を返します
__next__()返すイテレータ次の反復オブジェクト。何の次の値が返されないことができますがあれば、それは投げなければならないStopIteration例外を。

例1:デジタルイテレータを作成すると、徐々に1の増加、初期値1を返します。

class MyNumbers:
  def __iter__(self):
    self.a = 1
    return self
 
  def __next__(self):
    x = self.a
    self.a += 1
    return x
 
myclass = MyNumbers()
myiter = iter(myclass)
 
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))

例2:

class Counter(object):
    def __init__(self, low, high):
        self.current = low
        self.high = high

    def __iter__(self):
        return self

    def __next__(self):
        #返回下一个值直到当前值大于 high
        if self.current > self.high:
            raise StopIteration
        else:
            self.current += 1
            return self.current - 1
>>> c = Counter(5,10)
>>> for i in c:
...   print(i, end=' ')
...
5 6 7 8 9 10

注:イテレータは一度だけ使用することができます。投げたらStopIteration、それは同じ例外をスローしていきます。

>>> c = Counter(5,6)
>>> next(c)
5
>>> next(c)
6
>>> next(c)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 11, in next
StopIteration
>>> next(c)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 11, in next
StopIteration

例えば、ループ内のイテレータ:

>>> iterator = iter(c)
>>> while True:
...     try:
...         x = iterator.__next__()
...         print(x, end=' ')
...     except StopIteration as e:
...         break
...
5 6 7 8 9 10
イテレータを使用します:

イテレータがあり2つの基本的な方法は以下の通りですiter()next()
文字列、リスト、タプルまたはオブジェクトは、イテレータを作成するために使用することができます。

>>> list=[1,2,3,4]
>>> it = iter(list)    # 创建迭代器对象
>>> print (next(it))   # 输出迭代器的下一个元素
1
>>> print (next(it))
2

イテレータオブジェクトは、従来のトラバース文に使用することができます。

#!/usr/bin/python3

list = [1,2,3,4]
it = iter(list)   # 创建迭代器对象
for x in it:
    print (x, end=" ")

あなたはまた、次の()関数を使用することができます。

#!/usr/bin/python3
 
import sys         # 引入 sys 模块
 
list=[1,2,3,4]
it = iter(list)    # 创建迭代器对象
 
while True:
    try:
        print (next(it))
    except StopIteration:
        sys.exit()

イテレータ

Pythonで、使用してyield機能するジェネレータ(発電機)と呼ばれます。
違いは、通常の関数と、発電機があるということである返回迭代器機能只能用于迭代操作のポイントを理解しやすく、生成器就是一个迭代器。
それぞれの時間が降伏機能が一時停止を経験し、現在の動作情報をすべて保存、発電機の運転への通話中に返回 yield 的值并在下一次执行 next() 方法时从当前位置继续运行
ジェネレータ関数を呼び出すと、それはイテレータオブジェクトを返します。
例1:

>>> def my_generator():
...     print("Inside my generator")
...     yield 'a'
...     yield 'b'
...     yield 'c'
...
>>> my_generator()
<generator object my_generator at 0x7fbcfa0a6aa0>

上記の例では、yield文が単純なジェネレータを作成し使用し、それだけのような任意の他のイテレータと同様に、ループのために使用することができます

>>> for char in my_generator():
...     print(char)
...
Inside my generator
a
b
c

例2:

>>> def counter_generator(low, high):
...     while low <= high:
...        yield low
...        low += 1
... 
>>> for i in counter_generator(5,10):
...     print(i, end=' ')
... 
5 6 7 8 9 10

Whileサイクル、実行するたびyield場合ステートメント、及び発電機を停止する可変低状態の値を返します。発電機の次の呼び出しは、発電機は、可変低値を再開した後、凍結前の場所から増加した場合。発電機は、に続くwhileサイクルともう一度に来たyield声明...

例3:

#!/usr/bin/python3
 
import sys
 
def fibonacci(n): # 生成器函数 - 斐波那契
    a, b, counter = 0, 1, 0
    while True:
        if (counter > n): 
            return
        yield a
        a, b = b, a + b
        counter += 1
f = fibonacci(10) # f 是一个迭代器,由生成器返回生成
 
while True:
    try:
        print (next(f), end=" ")
    except StopIteration:
        sys.exit()


# 输出:0 1 1 2 3 5 8 13 21 34 55

私たちは通常、遅延評価のための発電機を使用しています。このような発電機は、大規模なデータ処理を使用するための良い方法です。あなたは、メモリ内のすべてのデータをロードしたくない場合は、発電機を使用することができ、データの一部のみがあなたに渡されます。

os.path.walk()関数は、コールバック関数と、現在使用して、この最も典型的な例であるos.walk発電機を。発電機のメモリ節約を使用します。

私たちは、次のような値、無限の数を生成するための発電機を使用することができます。

>>> def infinite_generator(start=0):
...     while True:
...         yield start
...         start += 1
...
>>> for num in infinite_generator(4):
...     print(num, end=' ')
...     if num > 20:
...         break
...
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

特徴的な発電機:彼らは再利用できません。

ジェネレータ式

式のリストを生成すると、高いメモリ効率を促進するために、発電機の高性能タイプと派生です。
例えば、1~9は正方形を加算される全ての数を試みます。

>>> sum([x*x for x in range(1,10)])

この例では、実際には最初、最終的な合計メモリの解放後、リスト内を歩いた後、メモリ内の正方形の値のリストを作成しています。あなたは、メモリ使用量が何の大きなリストであることを理解することができます。

することができますメモリジェネレータ式を保存するために使用されます

>>> sum(x*x for x in range(1,10))

文法ジェネレータは、常に両側とコンマできない、一対の括弧内発現を指示する必要があります。式の使用例次の例では、有効なビルダーです。

>>> sum(x*x for x in range(1,10))
285
>>> g = (x*x for x in range(1,10))
>>> g
<generator object <genexpr> at 0x7fc559516b90>

次の例では、我々は、ファイルを読み込みます、我々は、発電可能とジェネレータ式は、リンクされた'/var/log/cron'(私たちは、たとえば検索し、任意の与えられたタスクを表示し'anacron'、正常に実行します)。

我々は使用することができますshellコマンドtail -f /etc/crontab |grep anacron(に従って同じことを行うにはCtrl + C、コマンドの実行を終了します)。

>>> jobtext = 'anacron'
>>> all = (line for line in open('/etc/crontab', 'r') )
>>> job = ( line for line in all if line.find(jobtext) != -1)
>>> text = next(job)
>>> text
'25 6\t* * *\troot\ttest -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )\n'
>>> text = next(job)
>>> text 
'47 6\t* * 7\troot\ttest -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )\n'
>>> text = next(job)
>>> text
'52 6\t1 * *\troot\ttest -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )\n'

クロージャ

閉鎖(クロージャ)は関数は別のことで関数を返します私たちは、重複したコードを削除するためにクロージャを使用しています。次の例では、デジタル合計に簡単な閉鎖を作成しました。

>>> def add_number(num):
...     def adder(number):
...         #adder 是一个闭包
...         return num + number
...     return adder
...
>>> a_10 = add_number(10)
>>> a_10(21)
31
>>> a_10(34)
44
>>> a_5 = add_number(5)
>>> a_5(3)
8

デコレーター

デコレータ(デコレータ)一部のオブジェクトが動的にいくつかの新しい動作を追加するために使用され、我々はクロージャを使用したものと同じです。

関数が実行される前と後のいくつかのステートメントを印刷するには、簡単な例を作成します。

>>> def my_decorator(func):
...     def wrapper(*args, **kwargs):
...         print("Before call")
...         result = func(*args, **kwargs)
...         print("After call")
...         return result
...     return wrapper
...
>>> @my_decorator
... def add(a, b):
...     #我们的求和函数
...     return a + b
...
>>> add(1, 3)
Before call
After call
4
公開された33元の記事 ウォンの賞賛1 ビュー1234

おすすめ

転載: blog.csdn.net/weixin_44783002/article/details/104747594