ディレクトリmyprojectmain.pyがあり(または相当のJupyter Notebook),サブディレクトリsubにモジュールmod_a.pyがあり(関数func_a()が存在),このモジュールをmain.pyimportし,さらにこのモジュールにおいて,モジュールmod_b.py(関数func_b()が存在)をimportする状況を想定します.まず,subをパッケージとして認識させるため,subディレクトリに空のファイル__init__.pyを作成します.図示すると以下の状況です.

myproject/
  main.py
  sub/
    __init__.py
    mod_a.py (func_a())
    mod_b.py (func_b())

サブディレクトリsubは2つのモジュールを持ち,__init__.pyを用意しておくと,パッケージになります.すなわち,サブディレクトリがモジュールを束ねるパッケージです.

main.pymod_a.pyimport

main.pyでパッケージsub(あるいはサブディレクトリsub)に含まれる,mod_a.pyimportするには以下の様にします.

### myproject/main.pyにおいて
import sub.mod_a
sub.mod_a.func_a()

または,以下のようにすることもできます.

### myproject/main.pyにおいて
from sub import mod_a
mod_a.func_a()

さらに,以下のようすることもできます.

### myproject/main.pyにおいて
from sub.mod_a import func_a
func_a

このように,fromで指定したもの以下をimportすると,そのimportしたものを直接(パッケージ名やモジュール名を付けずに)呼び出せるようになります.func_a意外にも関数やクラスが存在している場合は,それぞれをカンマで区切って列挙するか,from sub.mod_a import *のようにアスタリスクですべてを読み込むこともできます.ただし,アスタリスクで読み込むと,何を読み込んだか分からなくなるので,避けた方がよいでしょう.

モジュールmod_aから同じサブディレクトリsubに存在する,モジュールmod_bimportする

この方法を見つけるのに苦労しました.以下のような方法があります.

### myproject/sub/mod_a.pyにおいて
from . import mod_b
mod_b.func_b()

同じサブディレクトリなので,つい,import mod_bとしたくなりますが,これはエラーとなります..の代わりにサブディレクトリ名subを用いて以下のようにすることもできます.

### myproject/sub/mod_a.pyにおいて
from sub import mod_b
mod_b.func_b()

ドット.を使えばサブディレクトリ名に無関係となるので便利です.

Follow me!