Python: こういった場所には注意してください
pythonはとても面白い言語です. とても便利な標準データベースと,簡単に実行できる多くの内蔵コマンドを提供しています. しかし,良いものが多すぎると,選択恐怖症になり,この標準データベースと,その基本的機関をうまく利用できないのです. 以下は, Pythonの初心者にとって非常にシンプルで効果的な罠です.
これは,StackOverflowで常に提起されている問題です. 完璧なコードが他人のコンピュータで実行され,エラーが発生すると,どのような経験になるのか,この時点で,自分のPythonバージョンが一致しているかどうかを確認する必要があります.
$ python --version
Python 2.7.9
python バージョン管理
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 (グローバル・インタプリタ・ロック) は,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では,古いスタイルをり,新しいスタイルをり,という2種類のクラスが存在する.Python 3を使用している場合,あなたはデフォルトの新しいスタイルをりを使用しています.Python 2で新しいスタイルをりを使用していることを確認するために,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 が,その関数が呼び出されるたびに,繰り返し引用されます. これは,非常に不必要な結果をもたらす可能性があります.