0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Jupyter Notebookで親ディレクトリの関数をスマートに読み込む方法:サブパッケージ対応編

0
Posted at

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:

もちろんです!ブログの内容やトーンに合わせていくつか候補を挙げますね。


ブログタイトル案

  1. Jupyter Notebookで親ディレクトリの関数をスマートに読み込む方法:サブパッケージ対応編
  2. Pythonで../src以下の複数モジュール・サブパッケージを効率的にimportする方法
  3. ノートブックで親ディレクトリの複数関数をまとめて使うパッケージ構成の作り方
  4. Pythonプロジェクトで親フォルダ以下の関数をスマートに管理・インポートする手順
  5. Jupyterで../src/causal以下の関数もまとめて使う!サブパッケージを活用したimport設計

もしブログのターゲット層や雰囲気(初級者向け・中級者向け・技術系)を教えていただければ、もっとピンポイントなタイトル案を出せます!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?