うまい寿司が食いたい。

うまい寿司が遠慮なく食べれるようになるまで,進捗とか垂れ流すブログ

pythonの相対インポートがわからなくなったメモ

たまにわからなくなるので、メモ書きです。

pytorchのgithubを読んでいると、次のような相対importが出てきます。

from .module import Module

https://github.com/pytorch/pytorch/blob/master/torch/nn/modules/conv.pyのLine 10とか。

これを参考に、自分でも相対インポートをしようと思いました。

src/  
├── bar.py  
└── foo.py

foo.py

def foo():
    print('foo')

bar.py

from .foo import foo

def bar():
   print('bar')
   foo()

if __name__ == '__main__':
     bar()

python bar.py を実行しようとしたのですが、このときには

Traceback (most recent call last):  
  File "bar.py", line 1, in <module>  
    from .foo import foo  
ImportError: attempted relative import with no known parent package

とエラーが出ます。
非常に初歩的な内容なのですが、.を用いた相対インポートを行う場合には、親ディレクトリが必要なようです。
なので、

src
├── main.py
└── module`
    ├── __init__.py
    ├── bar.py
    └── foo.py

のようにディレクトリ構成を変更して、

module1/__init__.py

from .bar import bar
from .foo import foo

__all__ = [foo, bar]

main.py

from module1 import foo, bar

if __name__ == '__main__':
    foo()
    bar()

として、main.pyを実行すれば、

foo
bar
foo

と返り値が得られました。

なので、相対インポートを使いたいときには親ディレクトリを作って使いましょう。

実行ファイルと同じ並びに相対インポートしたいpythonファイルがある場合には、. を使わず、 bar.py

from foo import foo

def bar():
   print('bar')
   foo()

if __name__ == '__main__':
     bar()

とすれば、インポートできます。