Python
pip

他人が書いたpython スクリプトを読む際に(中級ユーザーを想定)

プロジェクトに残されているpythonスクリプトがあって、その書いた人は、もうチームにいないということがある。
リポジトリからupdate かけて出てきた分のスクリプトとドキュメントでは説明が不足している場合があるだろう。

そんなときに私だったらどう対処するのかについてメモしてみる。

場合1: import 文、from文 で失敗する。

import に失敗するモジュールが標準的なものかどうか調べてみましょう。

人によっては、次のようにしてどのようなサードパーティのライブラリをimport しているのかどうかを示してくれていることがあります。そのような場合には、そのライブラリをどこから見つけてどのようにインストールすればよいのかがたどりようがあります。

import cv2 # https://opencv.org/

しかし

import _somemodule
_
とだけ書いてあるときでは、あなたがsomemoduleという標準的なサードパーティのライブラリがあるのか、その部署での自作モジュールなのかの区別がつきにくくなります。

まず、「somemodule python」でネット上で検索してみましょう。

それが標準的なライブラリであれば、Ubuntuなら apt-get install や pip install などでインストールできるようになります。

標準的なサードパーティのライブラリではなさそうだったとき:

 そのリポジトリにあるpython のモジュールを探してみましょう。

$ find . -name "*.py" -print

そうして somemodule.py というファイルが見つかった場合には、somemodule が呼び出せなかっただけということになります。
  PYTHONPATHの環境変数を指定して、somemoduleが呼び出されるようにします。

(より正確には、windowsの場合にはpyd ファイルの検索をすること、Linuxの場合はsoファイルを検索に加えることが必要になります。時には、pyファイルなしでpycファイルだけで提供されていることもありえます。またディレクトリに対して__init__.py ファイルがおかれている場合もあります。それらの場合には検索条件が変わってきます。)

標準的なサードパーティにもcheckoutの中にもなかったとき:

担当者の使用していたPCの中を探してみましょう。
担当者のPCの中には見つかる場合があります。その場合はcommit 漏れなので、commit しておきましょう。

場合2:何をするスクリプトか分からない。ある作業をするには、どのスクリプトを実行すればよいのかが分からない。

これは、その仕事を残した人がどこに何を記録を残しておいていてくれるかに関わっています。
スクリプトのあるディレクトリにReadme.md などとして書いてあれば、ネットワークドライブ上にPowerPointに書いてあるよりも見つけやすいというただ1点ですぐれています。

jupyter notebook のファイルは、きちんとメンテナンスさえされていれば、ドキュメントとスクリプトとで乖離を生じない点が魅力です。

残されたスクリプトを解読する側は、それらのスクリプトが何のためのスクリプトであるのか解読していく必要があります。

  • 三重引用符に囲まれたドキュメンテーションコメントを読む
  • if __name__ == "__main__": のブロックに書かれている処理の内容を読んでみましょう。

場合3:そのスクリプトの実行のさせかたがわからない。

  • sys.argv を使っていれば、コマンドラインで引数を与えて動作させる。
  • それ以外は、システムのコンソールで python スクリプト名.py を実行させるなり、spyder統合環境で [Run]を選択する。
  • その部分のコードを読んでみるしかありません。変数名や関数名がわかりやすい流儀でつけてあることを望むしかない。
  • 入力のファイル名をその部分にべたで書いていないか、
    • その場合は、そのファイル名を書き換えて利用する。

場合4:まだ使い慣れていないpythonの機能

人によっては、使い慣れていない機能やライブラリ由来の表現をみつけると、その意味に当惑することでしょう。
以下のヒントをもとに、解読をすすめてください。

  • files = [ p for p in glob.glob("*.dat") if os.path.isfile(p)] の表現が分かりにくい。
  • pandasのDataFrameの記述
    • df[df["name"] == "Sato"]のような記述。
      • PandasのDataFrameの扱いを学びましょう。

場合5:その関数がどこからきたのかがわからない。

from moduleName import *
の流儀で書かれていると、someFunc()などいった関数がどこからきているのか分かりにくくなります。
spyder 統合環境の場合だと、その関数名を選択して関数の定義されているところにたどり着くことができます。

場合6:入力画像が見つからない。

 画像処理・画像認識の分野の例題の場合には、スクリプトはあるのだが、入力の画像がないということがありがちです。そのような場合には、何かとにかく画像を用意して、代用してみましょう。それで十分なこともけっこうあります。
 分野によっては、よく使われる画像があります。画像ファイル名で検索すると、その画像が見つかることあります。ステレオ計測の場合には、よく使われる入力画像があったりします。tsukuba_l.png というファイル名で画像検索してみれは、ステレオ計測の分野でよく使われている画像を見つけることができます。

場合7:想定しているPythonのバージョンが実際に呼ばれているpythonとバージョンが異なる。

print 変数 # python2.x ではprint 文
print(変数) # python3.x では print 関数

Python2からPython3.0での変更点

そのスクリプトが想定しているpython のバージョンが違っていてうまくいっていない可能性もあります。

場合8:サードパーティのライブラリを使っている場所でエラーを生じる。

サードパーティのライブラリを使っているはずの場所で、「そのような関数がありません。」、「引数の数があいません」という主旨のエラーメッセージがでることがたまにあります。
本やブログに書かれた例題を実行するときに、例題が書かれた後に、サードパーティのライブラリが変更になったときに生じるのと同じエラーです。
そのようなエラーは、予め防ぐことはできません。生じたエラーメッセージをもとに検索して対象方法を見つけてください。

以上、他人が書いたpython スクリプトを読む際にヒントとなりそうなことを書いてみました。


引継いでもらうスクリプトにするためには

  • Python のコーディング規約 PEP8 に準拠する

  • Pythonの主要なLint(pep8, pylint, flake8)の設定方法まとめ

  • 何のためのスクリプト(あるいはモジュール)かが分かるようにしておくこと。
    将来、日本語に苦手な人が引継ぐ可能性があるときは、英語だけでドキュメンテーションコメントと通常のコメントを書いておいた方が無難。
     見知らぬ言語で端末やエディタの設定では、日本語としても表示されていない文字コードの入ったスクリプトファイルは、まるでファイルが壊れてしまっているようにしか見えない。