user:
ノートブックが ../src/* にある関数を読み込んで使えるようなpythonコードを書いてください。
assistant:
以下のように、Pythonノートブックで../src/ディレクトリ内のモジュールをインポートできるようにsys.pathにパスを追加するコードを書きます。
import sys
import os
# '../src/' の絶対パスを取得
src_path = os.path.abspath(os.path.join('..', 'src'))
# sys.pathに追加(重複を避けるために追加済みか確認)
if src_path not in sys.path:
sys.path.append(src_path)
# 例として、srcディレクトリ内のexample.pyのexample_functionをインポート
from example import example_function
# example_functionを使う
result = example_function()
print(result)
ポイント
-
sys.pathはPythonのモジュール検索パスリストなので、ここに../srcの絶対パスを加えることで、その中のモジュールをインポート可能にします。 -
example.pyは../src/ディレクトリ中のPythonファイル名(拡張子は不要)。 - インポートしたい関数やクラスに応じて
from example import example_functionの部分を書き換えてください。
必要に応じて具体的なモジュール名や関数名を教えていただければ、より詳細にお手伝いできます。
user:
関数が増えたときに、もっとスマートにかける方法はありませんか
assistant:
なるほど、関数が増えて複数のモジュールや関数をインポートする必要がある場合、毎回手動でfrom module import funcを書くのは面倒ですよね。
よりスマートに管理する方法をいくつかご提案します。
1. まとめてモジュールをインポートするためのラッパーモジュールを作る
../src/に__init__.py(空ファイル)を配置し、srcをパッケージ化します。
さらに../src/__init__.pyの中で必要な関数をまとめてインポートしておく方法:
# ../src/__init__.py の例
from .example import example_function
from .another_module import another_function
# ここにどんどん関数を追加
そしてノートブックではこう書くだけでOK:
import sys
import os
src_path = os.path.abspath(os.path.join('..', 'src'))
if src_path not in sys.path:
sys.path.append(src_path)
from src import example_function, another_function
print(example_function())
print(another_function())
2. 動的に../src内のモジュールを全部インポートする(上級)
../src以下の*.pyファイルをすべて検出して動的にimportし、モジュールの関数を取得するコードを書く方法です。
import sys
import os
import importlib
src_path = os.path.abspath(os.path.join('..', 'src'))
if src_path not in sys.path:
sys.path.append(src_path)
module_names = []
for filename in os.listdir(src_path):
if filename.endswith('.py') and not filename.startswith('__'):
module_name = filename[:-3]
module_names.append(module_name)
modules = {}
for name in module_names:
modules[name] = importlib.import_module(name)
# 例: example.pyのexample_functionを呼び出す
result = modules['example'].example_function()
print(result)
これは少しややこしくなるので、複数人で作業する場合はパッケージ化(1の方法)がおすすめです。
3. src をパッケージとしてインストール可能な形にして、pipなどから管理する(プロジェクトが大きい場合)
これは少し手間ですが、setup.pyを作ってローカルにインストールする方法もあります。
まとめると、一番オススメは
-
../srcをパッケージ化する(__init__.pyを置く) -
__init__.pyで公開したい関数をまとめてimportしておく - notebookは
from src import func1, func2のようにシンプルに書く
やり方です。
もし具体的な構成やファイル名がわかれば、さらにサンプルコードを用意しますので教えてください。
user:
この方針で行きます。
import sys
import os
src_path = os.path.abspath(os.path.join('..', 'src'))
if src_path not in sys.path:
sys.path.append(src_path)
from src import example_function, another_function
print(example_function())
print(another_function())
../src/causal/*.py のような位置にある関数を読み込むときはどうしますか?
assistant:
../src/causal/ のようにサブディレクトリに関数(モジュール)がある場合も、パッケージとして扱うのが基本です。
1. サブディレクトリ causal にも __init__.py を置く
-
../src/にすでに__init__.pyがあるとして、 -
../src/causal/にも空の(または必要に応じて初期化コードを書く)__init__.pyを置きます。
こうすることで、
src/ ← パッケージ
└─ causal/ ← サブパッケージ
├─ __init__.py
├─ module_a.py
└─ module_b.py
このような構成に。
2. __init__.pyの書き方
例えば、
-
../src/causal/module_a.pyに関数func_aがあるとします。
../src/causal/__init__.py に
from .module_a import func_a
from .module_b import func_b # もし他にあれば
../src/__init__.py に
from .causal import func_a, func_b
from .example import example_function
from .another_module import another_function
3. ノートブック上ではこうインポートできます
import sys
import os
src_path = os.path.abspath(os.path.join('..', 'src'))
if src_path not in sys.path:
sys.path.append(src_path)
from src import example_function, another_function
from src import func_a, func_b # causal の関数を直にインポート
print(example_function())
print(another_function())
print(func_a())
print(func_b())
または、より階層を明示するなら、
from src.causal import func_a, func_b
でもOKです。
まとめ
- サブディレクトリにも
__init__.pyを置いてサブパッケージ化 - サブパッケージの
__init__.pyで公開したい関数をまとめてimport - 上位パッケージの
__init__.pyからもまとめてimport可能(好みで) - Notebook側でのimportは、階層を含めて明示的に書くことができる
もし具体的なファイル名や関数名があれば、それに沿ったコード例も作成しますので遠慮なくどうぞ!
user:
ありがとうございます。以上の内容をブログに記録したいので、タイトルを考えていただけますか?
assistant:
もちろんです!ブログの内容やトーンに合わせていくつか候補を挙げますね。
ブログタイトル案
- Jupyter Notebookで親ディレクトリの関数をスマートに読み込む方法:サブパッケージ対応編
- Pythonで
../src以下の複数モジュール・サブパッケージを効率的にimportする方法 - ノートブックで親ディレクトリの複数関数をまとめて使うパッケージ構成の作り方
- Pythonプロジェクトで親フォルダ以下の関数をスマートに管理・インポートする手順
- Jupyterで
../src/causal以下の関数もまとめて使う!サブパッケージを活用したimport設計
もしブログのターゲット層や雰囲気(初級者向け・中級者向け・技術系)を教えていただければ、もっとピンポイントなタイトル案を出せます!