Python: こういった場所には注意してください
pythonはとても面白い言語です. とても便利な標準データベースと,簡単に実行できる多くの内蔵コマンドを提供しています. しかし,良いものが多すぎると,選択恐怖症になり,この標準データベースと,その基本的機関をうまく利用できないのです. 以下は, Pythonの初心者にとって非常にシンプルで効果的な罠です.
-
Pythonのバージョンは無視されています.
これは,StackOverflowで常に提起されている問題です. 完璧なコードが他人のコンピュータで実行され,エラーが発生すると,どのような経験になるのか,この時点で,自分のPythonバージョンが一致しているかどうかを確認する必要があります.
$ python --version Python 2.7.9python バージョン管理
pyenv は Python のバージョン管理ツールです.*nix システムでは. Mac OS では,brew install pyenv で簡単にインストールできます. Linux システムでは,自動インストーラ automatic installer があります.
-
コンピュータのシステムで コンピュータのシステムで
普通のコードよりも効率が悪く,読みづらい,あるいは曖昧なコードを書きながらも, "私は,一行で全ての問題を解決した"と誇らしげに言う人が多い. 例えば:
l = [m for a, b in zip(this, that) if b.method(a) != b for m in b if not m.method(a, b) and reduce(lambda x, y: a + y.method(), (m, a, b))]このコードは,この問題を説明するために私が書いたものです. しかし,私は実際に多くの人々がそれをやったのを見てきました. 単にリストやセットに何かを追加することで,複雑な問題を解くための方法を提示するならば,あなたはそれを失う可能性があります.
優れたコードは簡潔で,効率性と読みやすさに重点を置いています.
-
セットの初期化が誤りました.
これはもっと微妙な問題で,時には思いがけないでしょう. セット推論は,list推論のようなものです.
>>> { n for n in range(10) if n % 2 == 0 } {0, 8, 2, 4, 6} >>> type({ n for n in range(10) if n % 2 == 0 })この例では,setはコンテナにlistを入れているようなものです.
集合は重複しない,無秩序である.{}は空の集合だと考えられるが,空のディクトである.>>> {} {} >>> type({})set () を使って,この集合を初期化します.
>>> set() set() >>> type(set())注意:空の集合はset () として表現できるが,要素を含む集合はset () として定義される.[1, 2]) の姿
-
GILを誤解した
GIL (グローバル・インタプリタ・ロック) は,Python プログラムで,いつでも実行できるスレッドが1つしかないことを意味する。これは,私たちがスレッドを作成して,それが並行して動作することを期待できないことを意味する。Python インタプリタは,実際には,異なる実行スレッドをすばやく切り替えることをしている。しかし,これは非常に単純なバージョンである。多くのインスタンスで,プログラムが並行して動作する,例えば,C の拡張ライブラリを使用しているときのように。しかし,Python コードが実行される場合,ほとんどの場合,実行されません。つまり,Python のスレッドは,Java や c++ のように動作しません。
3 これは本当ですが,Pythonがスレッドを処理する方法は,あなたが期待するとは異なるという事実を変更しません.Rubyにも同様の状況があります (さらに,解釈器のロックがあります).
規定の解決策は,multiprocessingモジュールを使用することである。multiprocessingモジュールによって提供されるプロセスクラスは,基本的には,差異を十分にカバーできる。しかし,差異は,スレッドよりもはるかに高い費用である。したがって,並列で実行することは必ずしも良いものではない。
しかし,この問題はすべての Python プログラムに当てはまらない。PyPy-stm は Python の GIL 影響を受けない実装の例である。他のプラットフォームの JVM (Jython) や CLR (IronPython) に基づく実装には GIL の問題がない。
糸の類は,あなたが欲しいものではなく,あなたが得るものかもしれません.
-
古いスタイルクラスを使用する
Python 2では,古いスタイルを<unk>り,新しいスタイルを<unk>り,という2種類のクラスが存在する.Python 3を使用している場合,あなたはデフォルトの新しいスタイルを<unk>りを使用しています.Python 2で新しいスタイルを<unk>りを使用していることを確認するために,objectを継承する必要があります. または,あなたが作成した新しいクラスは,常に内蔵命令 int または list を継承しません.
class MyNewObject(object): # stuff here古いクラスが抱える非常に基本的な問題を修正しています. 興味があればドキュメントをご覧下さい.
-
誤った反復
ブログを始めてから,まずは,ブログを書き直す必要があります.
for name_index in range(len(names)): print(names[name_index])列表を巡るには,非常に簡単な文で実行できます.
for name in names: print(name)リストを簡素化するための他のツールもたくさんあります.例えば,zipは以下の2つのリストを巡るのに役立ちます.
for cat, dog in zip(cats, dogs): print(cat, dog)enumerate を使って,インデックスと値リストの変数について考えます.
for index, cat in enumerate(cats): print(cat, index)itertoolsには多くの機能があります. もしあなたが望む機能がitertoolsに含まれているなら,簡単にそれを使用できます. しかし,それを使用するためにあまりにもそれを使用しないでください.
スタック・オーバーフローの"大神"は,itertoolsの悪用により,解決に時間がかかりました.
変更可能なデフォルトのパラメータを使用
ブログを投稿する際には,
def foo(a, b, c=[]): # append to c # do some more stuff変数で定義されるパラメータは使用しないでください.
def foo(a, b, c=None): if c is None: c = [] # append to c # do some more stuffこの例は直感的に理解するのに役立ちます.
In[2]: def foo(a, b, c=[]): ... c.append(a) ... c.append(b) ... print(c) ... In[3]: foo(1, 1) [1, 1] In[4]: foo(1, 1) [1, 1, 1, 1] In[5]: foo(1, 1) [1, 1, 1, 1, 1, 1]同じ c が,その関数が呼び出されるたびに,繰り返し引用されます. これは,非常に不必要な結果をもたらす可能性があります.
- 1
