Python: この場所には注意してください.

作者: リン・ハーンイリダン作成日:2016年12月29日 13:46:12 更新日:

Python: この場所には注意してください.

python是一门非常有趣的语言。它提供了许多非常方便的标准库和许多内置命令是我们轻松完成任务.但是好东西太多了就有选择恐惧症了,以至于我们不能很好第利用这个标准库和它的基本机构。下面列出了一些对python新手来说很简单有效的陷阱。

  • Python のバージョンを無視します

これはStackOverflowで繰り返し提起される問題です. 完璧なコードが他人のコンピュータで実行されているときに,エラーがどのような経験になるかを確認するときに,あなたのpythonバージョンが一致しているかどうかを確認する必要があります. 知っているpythonバージョンでコードを実行していることを確認してください. Pythonのバージョンを確認するには,次のコードを使用してください:

  $ python --version
  Python 2.7.9

python バージョン管理

pyenvは, python のバージョン管理ツールである.残念ながら,これは *nix システム上でのみ動作する. Mac OS では, brew install で簡単に pyenv をインストールできます.

  • 単行本ですべての問題を解決することに困っています

多くの方が,私が"つのコードですべての問題を解決したと誇っていますが,彼らのコードは通常よりも低効率で,読み難い,曖昧なものになります. 例えば:

  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))]

リストやセットに何かを追加することで複雑な問題を解決する方法を示せば,あなたは損をする可能性があります. リストやセットに何かを追加することで,複雑な問題を解決する方法を示せば,あなたは損をする可能性があります.

コードを1行コントロールすることは,時には特に賢いように見えるが,大きな成果ではない.優れたコードは簡潔だが,効率性と読みやすいことに重点を置く.

  • セットを初期化したエラー

这是一个更加微妙的问题,有时候会让你措手不及。set推导式起来有点像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 は容器内のリストのようなものです. セットは重複値を持たない,並べ替えのないものである.{}は通常空のセットと考えられるが,空のディクトである.

  >>> {}
  {}
  >>> type({})

初期化したい場合は, set ((() を直接使います.

  >>> set()
  set()
  >>> type(set())

空の集合は集合として表されるが,要素を含む集合は集合として定義される (([1, 2]) となる.

  • GILを誤解している

GIL (global interpreter lock) は,Pythonプログラムで一度に実行できる文字列が1つしかないことを意味します. これは,私たちが文字列を作成して並行して実行することを期待できないことを意味します. Python解説者は実際には異なる文字列をすばやく切り替えるだけです. しかし,これは非常にシンプルなバージョンです. 多くの例ではプログラムが並行して実行されます.

Pythonには,これらの文字が真の文字だと説明しようとします. 3 これは本当ですが,Pythonが文字を処理する方法は,あなたが期待するようなものとは違います. Rubyにも同様の状況があります. (さらに,解説鍵があります).

規定された解決策は,マルチプロセッシングモジュールを使用することである.マルチプロセッシングモジュールの提供されたプロセスは,基本的に不一致をよく覆うことができる.しかし,不一致は,スレッドコストよりもはるかに高い.したがって,並行操作は必ずしも良くない.

しかし,この問題はすべてのPythonプログラムで発生するわけではありません.PyPy-stmはGILの影響を受けないPythonの実装の一例です.JVM (Jython) やCLR (IronPython) などの他のプラットフォームに構築された実装ではGILの問題はありません.

簡単に言うと,スレッドクラスを使用する際には注意してください.

  • 時代遅れのスタイルクラスを使用する

Python 2では,古い類と新しい類が2種類あります. Python 3を使っている場合は,デフォルトの類を使用しています. Python 2のクラスで新しい類を使用していることを確認するには,object を継承する必要があります. または,あなたが作成した新しいクラスでは,常に内蔵命令 int や list を継承しません. 言い換えれば,あなたの基類は,常にobject を継承する必要があります.

  class MyNewObject(object): # stuff here

古いクラスに存在していた基本的な問題を修正しています. 興味があるなら,ドキュメントを見てください.

  • 誤った繰り返しは

ニューヨーカーにとって非常に一般的な間違いは以下の通りです.

  for name_index in range(len(names)):
    print(names[name_index])

明らかにlenを使う必要はありませんが,実際にリストを横切るのは非常にシンプルな文でできます.

  for name in names:
     print(name)  

さらに,他のツールもたくさんあります. 例えば,zip は2つのリストを横切るのに使用できます.

  for cat, dog in zip(cats, dogs):
     print(cat, dog)

リストの変数について考えると,

  for index, cat in enumerate(cats):
     print(cat, index)

イターツールには多くの機能があります. イターツールにあなたが望む機能がある場合は,それを簡単に入手できます. しかし,それを使用するためにそれを使用しないでください.

itertoolsの乱用により,StackOverflowの大神様がそれを解決するのに多くの時間を費やしました.

変数のデフォルトパラメータを使用します.

ブログに載っているのは,

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


もっと見る