外部ファイルを読み込んで使用したいのですがうまくいきません。ご教示おねがいします。

**環境**  
CentOS7  
Python3.7  
Django2

```

    tree
    .app1
    |-aa.py 読み込まれるファイル
    |-bb.py 読み込むファイル
    
```

aa.py

```

    def hoge:
      print('hogehoge')
    
```

bb.py

```

    from . import aa
    aa.hoge()
    
```

Django からだと確かに bb.py で動くのですが、`python bb.py` で実行すると以下のエラーが出ます。

```

    from . import aa
    ImportError: cannot import name 'aa' from '__main__' (bb.py)
    
```

しかし、bb.py の `from . import aa` を `import aa` に変更すると `python bb.py` でも動きます

ここで質問なのですが、Djangoにおいても、ローカルにおいても同じコードでbb.pyを動かしたいのですがどうすればよいのでしょうか？  
ご教示お願いいたします。
CC BY-SA 4.0
2018-08-08T05:32:53.653
47341
2020-11-08T11:34:35.803
2020-11-08T11:34:35.803
3060
29649
question
python python3 django
Python importについて。外部ファイル読み込み
「app1」ディレクトリと同じディレクトリに以下のような「run.py」を置いて、それを起動する、ではダメですか?

```

    # coding: utf-8
    import app1.bb
    
```

* * *

pythonのインポートシステムはちょいとややっこしいので、ちゃんと説明できるかわからないし、そもそもこれであっているかどうかもわかりません。  
以下の話は、そのつもりで聞いてください。

「from . import aa」のような相対インポートは、同一パッケージ内のサブモジュール間でのみ使用できるようです。

もうちょっとわかりやすく(なっていないかもしれないけど)言うと、例えば

```

    sys.path += ['.']
    import app1.bb
    
```

とした場合、「app1」がパッケージとなり、その配下にある「aa.py」「bb.py」は「app1」パッケージのサブモジュール同士という関係になるので、「from
. import aa」というインポートは可能になります。

しかし、

```

    sys.path += ['./app1']
    import bb
    
```

とした場合、「bb」がパッケージとなるので、「aa.py」は別パッケージのモジュールと判断されます。

djangoは使った事がないのでよくわかりませんが、おそらく前者のパターンで「bb.py」がインポートされていのではないでしょうか。

もう一つ知っておきたい点として、「import aa」とした「bb.py」を「python bb.py」として実行するとなぜ成功するか。  
これは、「aa.py」が「bb.py」と同じディレクトリにあるから、という事が **直接的な理由** ではありません。

  1. 「python bb.py」と実行されると、「bb.py」の親ディレクトリが「sys.path」の先頭に追加される。
  2. 「import aa」が実行された際、「sys.path」で示されたディレクトリ内にある「aa」パッケージを探して、インポートされる。

という手順が踏まれるため、 **結果的に** 「bb.py」と同じディレクトリにある「aa.py」がインポートされます。

以上のことを踏まえて考えれば、「bb.pyを直接実行した際に相対インポートが使えない」という理由になるのではないでしょうか。

* * *

なんてつらつら書きましたが、書いている間にもう一つ対策を考えました。

```

    if __name__ == '__main__':
      import aa
    else:
      from . import aa
    
```

でもいいんじゃないでしょうか。  
djangoで動くかどうかわかりませんが。
CC BY-SA 4.0
2018-08-08T16:48:18.300
47360
2018-08-08T16:48:18.300
15473
47341
answer