Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

【Python】sys.pathに追加したディレクトリからimportする処理でPEP8に違反した際の対処

More than 3 years have passed since last update.

利用しているPythonのバージョンは3.6です。

もし間違った記述等があれば、コメントで指摘していただけるとうれしいです。

PEP8の違反内容

このようなディレクトリ構成で、scripts/execute.pyからlib配下の自作モジュールを読み込みたいとします。

.
├──scripts
│   └── execute.py
└──lib
    └── my_module.py

当初、execute.pyを次のように記述し、sys.pathにファイルを追加することで対処しようとしました。

import pandas as pd
import sys
sys.path.append('../lib')
import my_module

# (以下略)

ところが、これはPythonのコーディング規約であるPEP8日本語訳)に違反しているため、flake8等を利用している場合は次のツッコミが入ります。

E402 module level import not at top of file

日本語訳の該当箇所を引用しておきましょう。

import文 は常にファイルの先頭、つまり モジュールコメントや docstring の直後、そしてモジュールのグローバル変数や定数定義の前に置くようにします。

環境変数PYTHONPATHを設定して解決

ちょうど、Stackoverflowに同じ趣旨の質問がありました

この中に、いくつかの方法が回答されており、環境変数PYTHONPATHにディレクトリを追加する方法が本質的な解決方法のように思えました。(以下のリンクが紹介されていました)

(他にも、以下のような方法も紹介されていましたが、正直私には小狡いハックにしか見えません。)

  • パスの読み込み処理を記述したpathmagic.pyというファイルを用意し、それをimportする方法
  • try~except文で囲む方法

また、日本語の質問サイトであるteratailにも似た質問の回答がありました。Sphinxのコミッターの清水川さんの回答なので信憑性は高そうです。

sys.path をスクリプト内で調整することはあまり推奨されません。
色々なところで使いたいライブラリを置いているディレクトリが固定で、そのライブラリをimportしたいのであれば、環境変数 PYTHONPATH を設定する方法があります。

というわけで、PYTHONPATHにlibディレクトリを追加して対処しました。毎回利用する場合はbash_profileにでも書いておきます。

export PYTHONPATH="${PYTHONPATH}:/libディレクトリのフルパス/lib"

これにより、execute.pyからsys.path関連の記述を削除できました。

import pandas as pd

import my_module

# (以下略)

環境変数PYTHONPATHについて

本題とはずれるのですが、ここで「ライブラリ名と自作のモジュール名がバッティングした場合はどうなるの?」ということが気になって調べてみました。

こういうときは公式ドキュメントを読みましょう。公式のPythonチュートリアルの中に以下のような記述があります。

spam という名前のモジュールをインポートするとき、インタープリターはまずその名前のビルトインモジュールを探します。見つからなかった場合は、 spam.py という名前のファイルを sys.path にあるディレクトリのリストから探します。 sys.path は以下の場所に初期化されます:

  • 入力されたスクリプトのあるディレクトリ (あるいはファイルが指定されなかったときはカレントディレクトリ)。
  • PYTHONPATH (ディレクトリ名のリスト。シェル変数の PATH と同じ構文)。
  • インストールごとのデフォルト。

どうやら、PYTHONPATHにあるもののほうが優先されるようです。実際に試してもそのような挙動でした。

ninomiyt
株式会社LIFULLの愉快なPythonistaです
https://medium.com/@ninomiyt
lifull
日本最大級の不動産・住宅情報サイト「LIFULL HOME'S」を始め、人々の生活に寄り添う様々な情報サービス事業を展開しています。
https://lifull.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away