Pythonの相対インポートなど

import .baconとかfrom . import egg とかの書式ってなんなんだ?という疑問を小耳に挟んだので、なんかがんばっちゃうよ。

 

spam/egg.pyからspam/bacon.pyをインポートするときって、import baconとか書いちゃうよね。

だが、ちょっと考えてみて欲しい。

  • bacon.py
  • spam/egg.py
  • spam/bacon.py

こんな構成の場合はどうなるだろう。

spam/eggからimport baconすると、

このときのbaconは、spam/bacon.py だ。

このとき bacon.py は、spam/bacon.pyにかくされてしまっている。

じゃあ、トップレベルにあるbacon.pyはどうすればインポートできるのか?

こうした問題を解決するのがPEP328

http://www.python.org/dev/peps/pep-0328/

まずは、 from __future__ import absolute_import を使った場合と使わない場合。

 

absolute_import がない場合は、そのモジュールと同じパッケージにあるモジュールが優先される。

この場合、soam/bacon.pyに隠されてしまうため、トップにある bacon.pyは、__import__とか面倒なことをしないとインポートできなくなる。

 

absolute_importがある場合は、import baconってのは、トップレベルにbacon.pyがないといけない。

また、このとき 同じモジュールにbacon.pyがあってもインポートできない。

spam/bacon.py は、 from spam import bacon ってインポートする。

from spam import bacon って書き方はどちらの場合でも通用する書き方だけど、

パッケージの名前を変えたいときに、全部書き換えないといけなくなる。

このため、相対importであることを明示する方法がPEP328で追加されている。

from . import bacon と書くと、そのモジュールが属するパッケージからbaconをインポートする。

 

ちなみに、python3.xだと、デフォルトでabsolute_importになっている。

python2,3両方に対応する場合、相対インポートを意図している箇所は、明示的に相対インポートの書式にしましょうということ。

わかったかな?tell-kさん?

1 response
なるほど、分かりやすい解説。あざす!

>ちなみに、python3.xだと、デフォルトでabsolute_importになっている。
>python2,3両方に対応する場合、相対インポートを意図している箇所は、明示的に相対イン>ポートの書式にしましょうということ。

相対インポートである事を明示するのはマイナーな書き方じゃなくて、むしろ相対インポートさせたかったら(今後は)やるべき事なんだという事は理解できました。