この59個の方法は、あなたが知っているPythonコードの品質を書くには?

週末には、「高品質の効果的なPythonのPythonのコードを書くための59の効果的な方法」を読み終え、私はかなり良いを感じ、それは素晴らしい導く価値を持っています。以下は、事前の種子やビールに準備し、背中の推奨事項のほとんどは、これらの59件の勧告を記録するための最も簡単な方法であると説明し、例、記事の大規模な長さが追加されます!

考えるニシキヘビ方法

記事:Pythonの独自のバージョンを使用してください

パイソンの2つのバージョンがあります(1)がアクティブであり、python2とのpython3

(2)多くの一般Pythonランタイム環境などはCPython、Jythonの、IronPythonのとPyPyがあります。

プロジェクトを開発する場合(3)、優先順位は、のpython3を与えられるべきです

記事II:PEPは、スタイルガイドに従ってください

PEP8は、Pythonのスタイルガイドとコンパイルされたコードの形式で、次を参照してください。http://www.python.org/dev/peps/pep-0008

Pythonのコードを書くときは(1)、あなたは常にスタイルガイドPEP8に従ってください

(2)Pythonの開発者の大半は、コードスタイルの同じセットを使用する場合は、あなたが人々の協力プロジェクトをより助長することができます

(3)ライト・コードへの一貫したスタイル、あなたはそれ以降変更が簡単に仕事をしたことができます

記事III:Unicodeを使用した、バイト、strの違いを理解します

(1)python2は、Unicodeのstrを提供バイトのpython3のSTRに変更され、8ビットの元の値、STRデコードおよび実行のUnicode文字コード変換時に使用することを含むエンコード方法のバイト

(2)等、ファイルを開くために、常に、「RB」または「WB」バイナリモードにする必要があり、ファイルからバイナリデータを読み取る、またはバイナリデータがそこに書き込まれています

記事:複雑な式を置き換えるための補助機能

簡単そう単線式を理解するために、特に複雑で難しいの種類を記述し、パイソンの過剰な文法機能を使用する(1)開発者

(2)あなたは再使用するのと同じロジックにしたい場合は、我々はそうする必要があり、補助関数に式を複雑ください。

記事:シーケンスを切断する方法を理解します

0インデックスシーケンス長インデックスの開始または終了を、A場合は​​省略[:](1)は、余分なコードを書いてはいけません

(2)スライス開始および終了インデックスが範囲かどうか気にしない、我々は容易に、スライシング操作のための固定された範囲、フロントエンドまたは配列の後端から開始することができるようなものである[20]または[-20 :]

割り当てのリストは、スライス動作場合、元のリストは、それらが置換されていてもよい、異なる長さのものであっても、新しい値に関連した範囲内の値を置換する(3)がまだあります

記事VI:言葉スライシング操作ではなく、開始を案内しながら、終了ステップ

(1)この記事の主な目的は、読みにくいコードを恐れている、それは、2つの割り当て、実行するために切断の範囲に分解することを示唆し著者らは、別のステッピング切断を行います

(2)注意:使用すると、[:: --1]、時に予想されるエラーが発生した次の例を見て一致していません。

MSG = '谢谢' プリント( 'MSG:'、MSG)X = msg.encode( 'UTF-8')、Y = x.decode( 'UTF-8')、印刷( 'Y'、Y)Z = X [:: - 1] .decode( 'UTF-8')、印刷( 'Z'、Z)

出力:

ファイル

第7条:リスト非置換マップとフィルタを導出する式

それは、追加の書き込みラムダ式を必要としないため、(1)内蔵のマップおよびフィルタ機能を明確によりリストの内包、

(2)また、辞書や導出式の集合をサポートしています

第8条:Doが二つ以上の式を含むリストの内包表記を使用しません

IX:ジェネレータ式で大量のデータは、式のリストを導出するために書き換えられます

欠点(1)式のリストを導出します

導出では、入力シーケンスの各値に対して、新しいリストを作成する必要があり、それは、あり入力データが比較的小さいだけで一つの要素、何の問題が含まれていますが、入力データが非常に大きい場合Pythonは入れないで、実行時に一般化リスト内包とジェネレータであるジェネレータ式、ジェネレータ式を提供し、大量のメモリを消費し、クラッシュ、このような状況の顔を引き起こします全体の出力シーケンスが明らかにしたが、イテレータで評価されます。

一組の括弧内に配置された文言は、ジェネレータ式を構成することがリストリアライズを導出するために使用される式

(数字のI iについては)数= [1,2,3,4,5,6,7,8]のLi =印刷(LI)

<ジェネレータオブジェクト 0x0000022E7E372228で>

(2)高速ジェネレータ発現実行をつなぎ合わせ

記事:列挙可能な置換基は、との範囲

(1)結合の範囲にアクセスするためのテーブルでコードを列挙するために、その配列を利用するために書き換えられます

(2)、列挙するために第二のパラメータを提供することができる開始カウンタ値を指定するために使用され、デフォルト値は0であります

色= [、 '赤' '黒'、 '書き込み'、 'グリーン']の範囲(LEN(色))におけるiに対する#range命令方法:私の印刷(I、色[i])と#enumrate方法、で価値列挙(色):プリント(I、値)

第11条:横に2回の反復子と同時にジップ機能

(1)内蔵ジップ機能平行イテレータの複数横断することができます

(2)郵便番号ジェネレータへのpython3の対応を横断中の連続タプルを生成し、そしてジッパーは、直接生成完全ウェルタプルpython2であり、一度に全体のリストを返します

反復子が等しくない長さを提供されている場合(3)、ジッパーは自動的に終了を進めます

ATTR = [ '名前'、 '年齢'、 'セックス']の値=人々のpのため[ 'zhangsan'、18 '男'] =人のzip(ATTR、値):印刷(P)

ルール12:DOはforループとしながら、後ろに他のブロックを書き込みません

(1)Pythonプログラミング言語がサポートされていない多くの機能を提供し、そしてそれは、ループ内のブロックの真後ろにelseブロックを書くことです

印刷( 'ループ%D' %(i))を、他:範囲内のI(3)のための( '!elseブロック')印刷

上記の文言が誤解するのは非常に簡単です:サイクルが適切に実行終了していない場合は、他の実行、実際には、ちょうど反対

このようなアプローチは、直感的でなく、誤解でもないので、(2)は、バック他にリサイクル使用しないでください。

第13条:ついに除く/他に、各コードブロックの試みの使用の合理化/ /構造

試してみてください。それ以外の珍しい#:#除き、コードの実行を#ハンドル解除操作を:例外が発生していないとき、#は、最終的にはコードの実行を削減しようとすることができます

機能

第14条は:特別な状況を示すために例外を使用しようとすると、Noneを返しません。

値が0と空の文字列なしと同じように、Falseに表現湾を評価するための関数の特別な意味を表すために、この戻り値の(1)なし、それは、発信者を勘違いするのは簡単ではありません

むしろ、説明したように関数の呼び出し元を確認するためになし、例外文書を返すよりも、例外をスローする必要があり、例外的な状況に直面して機能した後、(2)、あなたはそれらを処理するコードを記述する必要があります

第15条:閉じられた袋に周辺の変数スコープを使用する方法を学びます

(1)どのようなクロージャを理解します

クロージャは、この関数の参照変数のスコープ、定義された範囲の関数です。

変数を参照して(2)式、スコープのPythonインタプリタトラバーサル順序:

A。現在のスコープの機能を

。Bの範囲の任意の周辺機器(例えば:現在の機能の他の機能を含んでいます)

C。現在のコードの範囲を含むモジュール(グローバルスコープとも呼ばれます)

D。組込みスコープ(ある、STR LEN等を含む機能の範囲)

これらの場所オフショーが定義されていない場合はE。変数名は、例外がスローされますNameError一致します

(3)割当、Pythonのルール・インタープリタ

変数に割り当てられたときに現在のスコープは、この変数を定義されている場合、この割り当ては、変数の定義としてみなされるPythonの電流範囲は、可変でない場合、その変数は、新たな価値を有するであろう

(4)非局所

非局所平均:上部スコープ内の変数を見つける必要があり、関連する変数の割り当てを与えるために時間、nomlocal唯一の制限は、モジュールレベルに適用するように拡張することができないことであり、これはグローバルスコープを汚染するのを防止することです

(5)グローバル

変数を表すためにグローバル割り当ては、直接モジュール変数のスコープを変更します

第16条:リストを書き換える直接返すようにファンクションジェネレータを考えます

リファレンス第9条

第17条:上記のパラメータの反復は、注意してください

複数の反復パラメータは、上記で入力した(1)関数は、引数が繰り返しオブジェクトであれば、それは奇妙な行動恐れがあり、注意が必要といくつかの値が欠落していなければなりません

次の2つの例を参照してください。

例1:

DEF正規化(番号):( '全'、合計)の合計= SUM(番号)印刷プリント( '数字'、数)結果= []数値の値の場合:パーセント= 100 *値/全result.append(パーセント)の戻り結果

番号= [15,35,80]プリント(正規化(数値))

出力:

ファイル

例2:発電機への番号

DEF楽しい():リチウムのI用のL​​i = [15,35,80]:収量I

プリント(正規化(楽しいです()))

出力:

ファイル

理由:唯一つの結果を生成イテレータ、繰り返し呼び出すとStopIteration例外の第二ラウンドで継続するには結果は存在しない、上にイテレータまたは発電機を投げました。

(2)Pythonのイテレータプロトコルを説明どのコンテナとイテレータITERと連動するための機能を内蔵し、及び関連式ループ隣

(3)同一の結果が次の関数の呼び出しを構築し、イテレータである場合、パラメータ値を取ることができるイテレータ又は容器、二ITER関数呼び出しのように、従来は、さらに、イテレータを可能にすることを決定

レイズはTypeError( 'コンテナを供給しなければならない'):ITER(数字)は、ITER(数字)である場合

第18条:パラメータの可変数の位置の視覚的ノイズを低減します

DEFステートメント(1)*引数は、関数は、位置パラメータの可変数を受信することができ

(2)関数が呼び出される配列位置パラメータの要素は、関数に渡されるように、操作者が*、使用することができます

(3)発電の使用機能が受け入れ、それは必要がありますので、我々は、比較の小さなを入力したパラメータの数を決定することができた場合にのみオペレータ、およびプログラムがメモリクラッシュが不足する可能性があり、引数式の可変引数を

(4)上記の関数で受信された*引数、パラメータ別の位置パラメータを追加し、エラーをトラブルシューティングすることは困難で発生することができ

第19条:行動を表現するために、オプションのキーワード引数

(1)関数のパラメータは、場所やキーワードによって指定することができます

(2)のみ位置パラメータを使用して関数を呼び出すためにこれらのパラメータの意味につながる可能性が明らかではないが、各パラメータのキーワードパラメータの意図を明確にすることが可能です

(3)この機能を使用すると、互換性のあるオリジナルの関数呼び出しのコードを維持するために、デフォルト値でキーワード引数を使用することができ、新しい動作を追加します

(4)オプションのキーワードパラメータは常にキーワードとして指定されるべきであり、パラメータを指定するための位置にあるべきではありません

第20節:なし、および動的パラメータを説明する文字列を持つ文書は、デフォルト値を持っています

印刷( '%sの:%s' は%(場合、MSG))DEF(MSG、場合= datetime.datetime.nowを())ログイン日時インポート時間をインポート

ログ( 'HI、最初')time.sleep(1)ログ( 'HI、第')

出力:

ファイル

同時に2つのショー、datetime.now()は、関数の定義は、各モジュールの時に決定されるパラメータのデフォルト値は、入ってくるロードされ、一度だけ実行され、一度だけ実行されるのでプログラムの起動時に、多くのモジュールがロードされます。私たちは、上記の機能を変更することができます。

日時インポート時にはデフログインポート(MSG、とき=なし):「」「引数とき:メッセージが発生したときの日時 『』」

= datetime.datetime.now()プリント( '%sの:%s' は%(MSG))Noneの場合なら

ログ( 'HI、最初')time.sleep(1)ログ( 'HI、第')

出力:

ファイル

デフォルト(1)のパラメータを評価し、プログラム及び読み出し機能にのみロードモジュールは、奇妙な動作を引き起こす可能性が、本一度、又は動的値[] {}などのために定義され

動的パラメータ値のキーワード(2)実際の、デフォルト値のデフォルト値は正式なしとして書かなければならないように、実際の行動のデフォルト値が関数に対応する文書の文字列で記述されています

第21条:コードだけ明確なことを確実にするためのキーワードパラメータとして指定することが

(1)キーワード引数は、関数呼び出しのより明確な意図を行うことができます

(2)簡単に混同間の各パラメータの機能について、あなただけの呼び出し側は、キーワードによってそれらを指定しなければならないことを確実にするためのキーワード宣言の仮パラメータを指定することができます。ブール関数が受け取るために複数のマーカーは、そうすべきです

クラスと継承

第22条:プログラムの状態を維持しようとする補助クラスではなく、辞書やタプルを使用して

私たちは辞書や情報ストアドプロシージャの一部のタプルを使用している場合は、しかし、徐々に変化する前に、刻々と変化する要求に、良い辞書やタプルの構造が定義されている必要があり、あまりにも、ネストされた多くの回があるでしょう:著者の意味があります拡張は、コードの問題につながる、と理解することは困難だろう。このような状況に遭遇し、私たちはクラスの入れ子構造を再構築することができます。

(1)他の辞書が含まれている辞書を使用しないでください、とあまりにも長いタプルを使用していません

(2)コンテナは、単純かつ不変データが含まれる場合に発現することができ、その後、完全なクラスを変更する必要があると、第一namedtupeを使用

注:namedtupleクラスは、使用namedtupleへのオプションより多くのデータの属性、不便のために、各パラメータのデフォルト値を指定することはできません

(3)は、より複雑になった場合、それは複数のセカンダリコードグループのクラスに分割されるべき辞書の内部状態を保存します

シンプルなインターフェイスの例としては、むしろクラスよりも、機能を受け取る必要があります。第23条を

(1)単純なインタフェースPYTHON様々な構成要素を接​​続するために、それは直接関数に渡されることが一般的であり、渡されたそのクラスのクラス、インスタンスを定義していません

クラスとして引用され、したがって、それらは表現の内側に配置することができるオブジェクトの他のタイプと同じであることができる機能および方法の(2)Pythonの種類

呼び出された(3)コールクラスのインスタンスを作ることができる特別な方法は、通常のPythonなどの関数呼び出しとして得ることができます

第24条:オブジェクトの建設に多形型の共通の@classmethod

Pythonの種では、オブジェクトがサポートするマルチステート、マルチステートクラスもサポートしていないだけ

Pythonプログラムの種類(1)において、各クラスは、コンストラクタ、有することができる初期化方法を

(2)オブジェクトクラスを構築するために同様の方法で、コンストラクタに機構を@classmethod

(3)、我々は構築することができ、クラスメソッド機構によってよう多目的より具体的なサブクラスでスプライシングさ

MapReduceのを達成するために以下の処理を説明するための例として、ファイル内の行の数を数えます。

(1)アイデア

ファイル

(2)コード

デフ(自己を)読み:クラスPathInputData(入力データ)例外NotImplementedErrorが送出されます:defインポートは、インポートOSクラス入力データスレッドのinit(自己、パス):スーパー()を。INIT()self.path =パス

デフ読んで(自己):戻りオープン(self.path).read()

クラスワーカー:デフのinit(自己、INPUT_DATA):self.input_data = INPUT_DATA self.result =なし

デフ(自己)マップ:昇給をNotImplementedError

デフ(自己)削減:昇給をNotImplementedError

クラスLineCountWorker(労働者):デフマップ(自己):データ= self.input_data.read()self.result = data.count( '\ n' は)

self.result + = other.result:DEF(自己、他)を低減

デフgenerate_inputs(DATA_DIR):名os.listdir(DATA_DIR)中:収量PathInputData(os.path.join(DATA_DIR、名前))

DEF create_workers(input_list):input_listでINPUT_DATAための労働者= []:workers.append(LineCountWorker(INPUT_DATA))リターンワーカー

DEF(作業者)を実行:[労働者Wのthreading.Thread(目標= w.map)]スレッド=スレッド内のスレッドのために:スレッド内のスレッドのthread.start():thread.join()

まず、休息=労働者[0]、研究者[1]労働者のための残りの部分:first.reduce(ワーカー)戻りfirst.result

DEFのMapReduce(DATA_DIR):入力= generate_inputs(DATA_DIR)労働= create_workers(入力)リターン実行(作業者)

もし名前 == " メインプリント(MapReduceの( 'D:\ mapreduce_test'))のMapReduce"

上記のコードは、次@classmethodの再利用を改善するために、様々な構成要素は非常に面倒なスプライシングをあります

輸入スレッド輸入OSクラス入力データ:デフ読んで(自己):昇給NotImplementedError

@classmethodデフgenerate_inputs(CLS、DATA_DIR):昇給NotImplementedErrorクラスPathInputData(入力データ):デフのinit(自己、パス):スーパー()。INIT()self.path =パス

デフ読んで(自己):戻りオープン(self.path).read()

@classmethod DEF generate_inputs(CLS、DATA_DIR):名os.listdirで(DATA_DIR):収量CLS(os.path.join(DATA_DIR、名))

クラスワーカー:デフのinit(自己、INPUT_DATA):self.input_data = INPUT_DATA self.result =なし

デフ(自己)マップ:昇給をNotImplementedError

デフ(自己)削減:昇給をNotImplementedError

@classmethod DEF create_workers(CLS、input_list):労働者= [] input_listでINPUT_DATA用:workers.append(CLS(INPUT_DATA))リターンワーカー

クラスLineCountWorker(労働者):デフマップ(自己):データ= self.input_data.read()self.result = data.count( '\ n' は)

self.result + = other.result:DEF(自己、他)を低減

DEF(作業者)を実行:[労働者Wのthreading.Thread(目標= w.map)]スレッド=スレッド内のスレッドのために:スレッド内のスレッドのthread.start():thread.join()

まず、休息=労働者[0]、研究者[1]労働者のための残りの部分:first.reduce(ワーカー)戻りfirst.result

DEFのMapReduce(DATA_DIR):入力= PathInputData.generate_inputs(DATA_DIR)労働= LineCountWorker.create_workers(入力)リターン実行(作業者)

もし名前 == " メイン ":プリント(MapReduceの( 'D:\ mapreduce_test'))

MapReduceの修正

クラス多型によるメソッドの実装メカニズム、我々は具体的なクラスやスプライシングを構築するために、より汎用性の高い方法を使用することができます

第25条:スーパー親と初期化

あなたはスーパーの方法を用いて詳細に説明python2から開始した場合は、ここだけにし、MROのpython3を使用し、多くのスペースを必要とし

(1)MROは、スーパークラスとの間の初期化シーケンスを配置する方法の解決順序、標準的な手順であり、深さ優先では、左から右に、それはまた、共通の基底クラスことダイヤモンドの上部を確実にするのinitメソッドを一度だけ実行されます

スーパーの利用(2)のpython3

で、パラメータなしでの実施例の効果を、コールのスーパーのpython3方法を提供するクラスと同じ自己は、スーパーコールします

クラスA(塩基):DEFのinit(自己、値):スーパー(階級、自己).INIT(値)

クラスA(ベース):デフのinit(自己、値):スーパー()のinit(値)**。

2つの方法上記の推奨は、この方法は、のpython3とすることができるクラスが現在のクラスを指し、そして正確な変数はPython2の中で定義されていないクラスメソッド

(3)は、常に親クラスを初期化するために、内蔵のスーパー機能を使用する必要があります

第26条:多重継承成分のみ制作ツールミックスに使用した場合

Pythonは、組み込みのメカニズムをプログラミングの数を提供するオブジェクト指向のプログラミング言語で開発者が適切に多重継承を実装することができますが、我々は、ミックスインクラスの準備を考え、私たちが使用しなければならない場合には、多重継承を回避しようとしてくださいミックスで小さなクラスで、他のクラスは唯一のほかに、その属性のインスタンスを定義せずに、提供するために必要となる場合があり、追加のメソッドのセットを定義し、それは彼らの呼び出しをユーザーに要求する初期化機能を

(1)を行うために複数の継承を使用しない、ミックス中の成分の効果を達成するために使用することができます

(2)各関数は、プラグイン可能なミックスインコンポーネントとして実装され、その後、彼らが必要なコンポーネントを継承関連するクラスを作成され、あなたがクラスのインスタンスの動作をカスタマイズすることができます

(3)ミックスインの成分をカプセル化の単純な行為、そしてあなたは、ミックス中の複合体の行動を複数の組み合わせを使用することができます

第27条:多目的公共財産、私有財産少ないです

Pythonは、厳密な文法からプライベートフィールドのプライバシーを確​​保されていない、簡単な言葉で、私たちは大人です。

個人的な習慣:_xxx単一指定された代表者が保護され、XXXダブルアンダースコアの開始と終了ではない_プライベート表すために、システムによって定義されたプロパティとメソッドXXX__

クラスの人々:__name = "zhanglin"

デフのinit(自己):自己.__年齢= 16

プリント(人々 。dictの)P =ピープル()印刷(P。辞書

見つけるの名前と(_ +クラス名のプロパティ名)となっている、年齢プロパティ名が変更された、唯一の疑似民間説明ように、このように、__XXXでこのネーミングを変更

(1)のpythonコンパイラは、厳格なプライバシーのプライベートフィールドを保証することはできません

(2)民間にない盲目的に財産を行いますが、最初から良い仕事の計画を行う必要があり、そしてスーパークラス内部APIのサブクラスへのより多くのアクセスを許可します

(3)は、開発者が私有財産を使用しようとすると、これらのフィールドのサブクラスへのアクセスを制限するのではなく、文書内のサブクラス伝えるために保護された財産のより多くの使用、およびこれらのフィールドの使用の合理化する必要があります

彼らのコントロールからサブクラスは、我々は、名前の競合を避けるために私有財産を考えることができる唯一の(4)

第28条:継承collections.abcは、カスタムコンテナ型を達成するために

collections.abcモジュールは、コンテナの種類ごとに共通の方法を提供する抽象基底クラスのセットが定義されている必要があり、あなたは独自のソースを参照することができます

すべて= [ "Awaitable"、 "コルーチン"、 "AsyncIterable"、 "AsyncIterator"、 "AsyncGenerator"、 "ハッシュ可能"、 "反復処理可能"、 "イテレータ"、 "ジェネレータ"、 "可逆"、 "サイズの"、 "コンテナ" 、 "呼び出し可能"、 "コレクション"、 "設定"、 "MutableSet"、 "マッピング"、 "MutableMapping"、 "MappingView"、 "KeysView"、 "ItemsView"、 "ValuesView"、 "順序"、 "MutableSequence"、 " **]、」バイト文字列

(1)カスタムサブクラス比較的単純な場合は、直接Pythonのコンテナタイプから継承することができる(例えば、リスト、辞書)に

(2)は、特別なメソッドの多くを記述する必要があり、コンテナカスタムの正しい種類を達成するために望んでいます

(3)抽象基底クラスcollections.abcモジュールから継承することができる自家製容器型の製造、我々は、基本クラスのサブクラスでは、適切なインタフェースと動作を含むことを保証することができます

公開された38元の記事 ウォンの賞賛1 ビュー2192

おすすめ

転載: blog.csdn.net/wulishinian/article/details/104813457