プログラムとか 思ったこととか 徒然ブログ 投稿一覧へ戻る

タグ "Effective" が付いている投稿一覧

【 Effective Python, 2nd Edition 】@classmethod ポリモーフィズム ( polymorphism ) を利用して、複数の派生クラスをよりジェネリック ( generic ) に活用しよう!

Tags: Python , Effective , polymorphism , generic , classmethod

Published 2020年7月8日23:11 by T.Tsuyoshi

Python では、インスタンスに限らずクラスでもポリモーフィズム ( polymorphism ) を活用できます。 これはどういうことなんでしょうか? そして、どんなときに活用できるんでしょうか? Polymorphism は、クラス階層内におけるそれぞれの派生クラスが、同じインターフェースながら機能的には異なる独自のものを提供することを可能にします。 今回目指すのは MapReduce モデルの実装です。 MapReduce モデルは、ある処理を複数のサブプロセスに分割して実行し(map)、それぞれの結果を統合して1つの結論を導く(reduce)、分散コンピューティングモデルの1つです。 まずはデータを提供するためのベースとなる抽象クラスを用意します。 このクラスの派生クラスでは read() という共通インターフェースを提供します。 class …

【 Effective Python, 2nd Edition 】インスタンスを関数として利用可能にする __call__ 特殊関数を含んだクラスを定義してフック ( hook ) として利用することで、既存の API の機能拡張を計ろう!

Tags: Python , Effective , closure , defaultdict , hook , __call__

Published 2020年7月7日20:57 by T.Tsuyoshi

数多くの Python 組み込み API では、引数として関数を受け取ることでその「振る舞い」をカスタマイズできるようになっています。 このようなことをフック ( hook ) と呼んでいますが、定義には若干曖昧なところが見受けられ、「API の振る舞いを渡す関数によってカスタマイズする」行為そのものを指す場合や、API の振る舞いをカスタマイズするために渡す「関数自身」を指す場合等があるようです。 このことを踏まえて、この記事で「フック」という言葉が出てきた場合は、読まれている方々それぞれが解釈しやすい意味合いで捉えていただければ、と思います。 さて、本題に戻りまして、API 側からみればこのフックというのは、実行中にこちら側のコードを呼び出す手段、であるわけです。 分かりやすいところでは、list タイプの sort メソッドが、要素をどのように並べ替えるのか、ということを決定するために key …

【 Effective Python, 2nd Edition 】組み込みタイプ ( built-in types ) を利用していてネストが深くなってきたらクラス ( class ) を作成する頃合いです、の巻

Tags: Python , dictionary , Effective , namedtuple , defaultdict , class , oop , refactoring

Published 2020年7月6日22:30 by T.Tsuyoshi

Python はやはり OOP (Object-Oriented Programming) 言語ですから、いかにうまくクラスを設計、利用するかで将来的な拡張性、メンテナンス性が大きく左右されます。 基本的なことではありますけど「最重要」と言い切っても過言ではないと思いますので、今回からはクラスやインターフェース関連の話題を中心に取り上げていきます。 Python における辞書型 ( dictionary type ) は、オブジェクトの属性の保存、更新はもちろん、ある意味新たな属性の追加等にも利用可能な非常に優れた型ですね。 さてさて、生徒全員の成績を保存しておくプログラムを組みました。 辞書を利用することで、前もって生徒の名前や人数が分からなくても全然困ることはありません。 class SimpleGradebook: def __init__(self): …

【 Effective Python, 2nd Edition 】throw() メソッドを利用したジェネレータ ( generator ) 内部での状態遷移はなるだけ避けましょう。ネストが深くなってコードの読解性が落ちちゃいますよ!

Tags: Python , generator , iterable , send , iterator , yield , Effective , throw

Published 2020年7月4日23:31 by T.Tsuyoshi

yield from 文や send() メソッドに加えて、ジェネレータを使う際にあまり利用されていない機能として throw() メソッドがあります。 ジェネレータが throw() メソッドによって呼び出されると、再開した時点の、すなわち、前回終了した時点の yield 式自体が渡された例外を即座に投げます。 そして、ジェネレータ内でその例外をキャッチしない場合、呼び出し元にその例外を投げてジェネレータはその時点で動作を終了します。 class MyError(Exception): pass def my_generator(): yield 1 …

【 Effective Python, 2nd Edition 】ジェネレータ ( generator ) に値を注入したいなら、yield from 式と send() 関数の併用よりも、注入する値を提供するイテレータ ( iterator ) を渡しましょう、の巻

Tags: Python , generator , send , iterator , yield , Effective

Published 2020年7月3日20:34 by T.Tsuyoshi

さて今回取り上げる話題は前回の ジェネレータの反復作業中に外部から値を注入して出力結果に反映させよう!代入式の右辺に yield 式があったり、send() メソッドを使ったり!の巻 の続き、という位置づけですので、読んでいない方は目を通しておいていただいた方が理解しやすいと思います。 前回は、send() メソッドを利用するとジェネレータの yield 式に値を設定することが可能になり、その値を利用して次の yield 式からの出力値を変更可能、ということを説明しました。 さて今回は、より複雑な波形を出力したい、という「足るを知らない」人間の欲望に基づいてプログラムをアップデートしなければいけなくなったところから話が始まります。 目指すは1周期の正弦波 (サイン波) ではなく、1周期ごとに異なる振幅、ステップ数からなる複数周期の波形データの出力、です。 これを実現するための実装方法の1つは、yield from 式を利用して複数のジェネレータを組み合わせる方法です。 まずは通常の …