Python: こういった場所には注意してください

作成日:: 2016-12-29 13:46:12, 更新日::
comments   0
hits   1385

Python: こういった場所には注意してください

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を誤解した

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 が,その関数が呼び出されるたびに,繰り返し引用されます. これは,非常に不必要な結果をもたらす可能性があります.