関数型プログラミングパイソン:歩留まりのPythonの使用法の予備的な分析機能

この記事では、歩留まりのPythonの関数を記述し、歩留まりを基準の下で、IBMの公式ウェブサイトの開発者向けドキュメントの翻訳から、一般的に使用される機能でファンクション・ジェネレータであることを必要としている友人もでき
、あなたが、聞いたことがあるかもしれ関数はPythonのジェネレータ(発電機)での歩留まり、どのような発電機と呼ばれていますか?

のは、歩留まりの概念を示すために、一般的なプログラミングのトピックで、脇発電機を入れてみましょう。

フィボナッチ数を生成する方法

フィボナッチ(フィボナッチ)は、第一及び第二の数を除いて、任意の数が一緒になって最初の2つの数字によって得ることができ、再発性配列の非常に単純な一連あります。最初のNフィボナッチ数列の出力コンピュータプログラムフィボナッチ数は、多くの初心者が簡単に次の関数を書くことができることを非常に単純な質問です:

1.シンプルな出力に最初のNの列のフィボナッチ数をリスト

def fab(max):
 n, a, b = 0, 0, 1
 while n < max:
  print b
  a, b = b, a + b
  n = n + 

実行FAB(5)、我々は次のような出力が得られます。

>>> fab(5)
1
1
2
3
5

関数が戻るなし、他の機能は、生成された関数内の列数を取得することはできませんので、その結果問題はないが、経験豊富な開発者が指摘する、印刷機能との直接デジタル印刷はは、Fab、Fabの貧しい機能の再利用性の原因となります。

再利用性FABの機能を向上させるために、それが直接の列の数をプリントアウトする最善ではありませんが、リストを返します。以下は、Fab番目のバージョンの後に書き換えの関数であります:

Nの第二版の前に2.出力フィボナッチ数列リスト

def fab(max):
 n, a, b = 0, 0, 1
 L = []
 while n < max:
  L.append(b)
  a, b = b, a + b
  n = n + 1
 return L

リストFABは、機能をプリントアウトすることができ、次の方法を返します。

>>> for n in fab(5):
...  print n
...
1
1
2
3
5

あなたはメモリを制御したい場合は、パラメータmaxの増加とともに増加する書き換えファブ機能は、要件を満たすためにリストの再利用を返しますが、より多くの経験を積んだ開発者は、関数がメモリの動作に占めることを指摘します職業、それはリストを使用するのが最善ではありません

中間結果を保存するには、しかし、反復可能なオブジェクトを反復処理します。例えば、Python2.x、コードで:
反復可能オブジェクトを介して3反復リスト

 for i in range(1000): pass

これは、1000年のリストの要素、およびコードが発生します。

for i in xrange(1000): pass

リストは1000年の要素が生成されていないが、各反復で次の値を返すために、それは非常に少ないメモリ空間を占めます。xrangeのリストを返しますが、反復可能なオブジェクトを返しませんので。

私たちがサポート反復可能なクラスの機能を書き換えることができたFabの利用は反復可能な、以下は、Fabの3番目のバージョンである:
リスト4. 3番目のバージョン

class Fab(object):
  
 def __init__(self, max):
  self.max = max
  self.n, self.a, self.b = 0, 0, 1
  
 def __iter__(self):
  return self
  
 def next(self):
  if self.n < self.max:
   r = self.b
   self.a, self.b = self.b, self.a + self.b
   self.n = self.n + 1
   return r
  raise StopIteration()

メモリ使用量の連続した一連の次の番号を返す)(次でFabクラスは常に一定です。

>>> for n in Fab(5):
...  print n
...

しかし、コードのこのクラスの書き換えバージョンの使用は、初版のファブ機能をより簡潔であるから遠いです。我々はまた、反復可能な効果を得る一方で、初版のファブ機能のシンプルさを維持したい場合は、収率が便利になる:
リスト5.歩留まり第4版を

def fab(max):
 n, a, b = 0, 0, 1
 while n < max:
  yield b
  # print b
  a, b = b, a + b
  n = n + 1
  
'''

Fabおよび初版に比べての第四のバージョン得られた結果を反復可能で簡潔性を維持しながら、唯一の印刷bは、Bを得るように変更。

FAB FABとまったく同じの第二版の第四版を呼び出します。

>>> for n in fab(5):
...  print n
...

降伏関数はもはや通常の関数であると簡単に言えば、役割の機能をもたらすが、発電機になることはありません、Pythonインタプリタは、発電機としてそれを扱います、FAB(5)は、ファブの機能を実行しない呼び出し、しかし、反復可能なオブジェクトを返します!ループはFAB機能コードの内部で実行される各ループのために実行された場合、収量bに実行されたとき、FAB関数は繰り返し、次の反復の値を返し、コードは、次のステートメントの収量Bの実行、および機能を継続しますローカル変数とブレーク実行前の最後の外観はまったく同じなので、関数が再び降伏するまで実行を継続します。

(FAB(5)は次の()メソッドを持つジェネレータオブジェクトであるため)あなたはまた、我々はより明確に、ファブプロセスの実装を見ることができるように、次の手()メソッドの(5)FAB呼び出すことができます。

6.実行プロセスをリスト

>>> f = fab(5)
>>> f.next()
1
>>> f.next()
1
>>> f.next()
2
>>> f.next()
3
>>> f.next()
5
>>> f.next()
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
StopIteration

関数が実行されると、発電機は自動的に反復が完了したことを、呼び出すとStopIterationを上げます。ループのために、異常な処理を呼び出すとStopIterationことなく、通常のサイクルが終了します。

私たちは、次のような結論を引き出すことができます。

収量は、発電機との関数であり、発電機を生成するために、通常の関数と異なる点は、関数呼び出しのように見えますが、それはループのために自動的に次を呼び出しますで()(次を呼び出すまで(任意の機能コードを実行しません。 ))を開始しました。実行が、各実行の機能に基づいて、プロセスの実行プロセスが、yield文の区切りにアウトと値の反復、継続する利回りから次の文の次の実行を返します。降伏関数のように見えますが、通常の実行の過程で何度か中断された、それぞれの割り込みは返します現在の反復値が得られます。

収量利点は明らかであり、発電機を書き換える機能能反復の値を得て、次の()コードシンプルが、非常に明確な実装プロセスだけでなく計算するクラスのインスタンスに保存された状態よりも低いです。

関数は、特別なファンクションジェネレータであるかどうかを判断する方法は?分析isgeneratorfunctionを利用することができます。

isgeneratorfunction裁判官を使用してリスト7.

>>> from inspect import isgeneratorfunction
>>> isgeneratorfunction(fab)
True

(5)およびFab FAB区別するために、発電機機能、およびFab(5)工場では、リターン・ジェネレータFAB、そのような定義とクラスとの間の差の例を呼び出します。

リスト8クラス定義とクラスの例。

>>> import types
>>> isinstance(fab, types.GeneratorType)
False
>>> isinstance(fab(5), types.GeneratorType)
True

FABは、反復的ではなく、FAB(5)の反復です。

>>> from collections import Iterable
>>> isinstance(fab, Iterable)
False
>>> isinstance(fab(5), Iterable)
True

各呼び出しFAB機能は、互いに独立して、各インスタンスを新しいジェネレータのインスタンスを生成します。

>>> f1 = fab(3)
>>> f2 = fab(5)
>>> print 'f1:', f1.next()
f1: 1
>>> print 'f2:', f2.next()
f2: 1
>>> print 'f1:', f1.next()
f1: 1
>>> print 'f2:', f2.next()
f2: 1
>>> print 'f1:', f1.next()
f1: 2
>>> print 'f2:', f2.next()
f2: 2
>>> print 'f2:', f2.next()
f2: 3
>>> print 'f2:', f2.next()
f2: 5

リターン・アクション

ノーリターンがない場合は、直接呼び出すとStopIterationスロー実装プロセスでのリターンは、反復を終了した場合にジェネレータ関数では、実行するためのデフォルトの機能は、完成されています。

もう一つの例

別の例では、ファイルの読み込みの収量から来ています。あなたはファイルオブジェクトに直接読み取る()メソッドを呼び出した場合、それは予測不可能なメモリフットプリントにつながります。良い方法は、連続的にファイルの内容を読み取るために、固定長のバッファを使用することです。降伏することで、我々はもはや必要がファイルを読むためにイテレータクラスを書くために、あなたは簡単にファイルを読み込むことができます。

9.降伏リストの別の例

def read_file(fpath):
 BLOCK_SIZE = 1024
 with open(fpath, 'rb') as f:
  while True:
   block = f.read(BLOCK_SIZE)
   if block:
    yield block
   else:
    return

上記の収量、収量の基本的な概念と使用するだけの簡単な紹介で、我々はより強力な用途があるのPython 3での将来の記事で説明します。

注:この記事のコードは、Python 2.7に貫通してデバッグしています

最後に、我々は非常に広いPythonの学習リソースの収集をお勧めします、[入力する]をクリック]、ここでのビジネス経験の可能性がある、経験、研究ノートを学ぶ前に、私のコレクションであり、プロジェクトの戦闘への情報に基づいてゼロに沈静化、我々は一番下に、メッセージを残し、前方に置くことを知らないことができ、我々は進歩を一緒に勉強します

公開された44元の記事 ウォン称賛56 ビュー60000 +

おすすめ

転載: blog.csdn.net/haoxun10/article/details/104908622