Log
published: 2021-12-18
pythonのクラスメソッドを異なるファイルで管理する
業務で使用するパッケージなどは、改修の都度に関数が追加されたりするので、コード量が多くなりがちです。
なので「クラスを定義したいけど、クラスメソッドはファイルごとに管理したい」という場合があるのではないでしょうか。
今回は、あるクラスをpythonで定義したうえで、クラスメソッドをファイルごとに管理する方法になります。
実装
パッケージは下記のような配置になります。
myproject内に、クラスが定義されている"some_class.py"、クラスメソッドを定義している"some_pkg1.py"、"some_pkg2.py"を用意します。
myproject
├── some_class.py
├── some_pkg1.py
└── some_pkg2.py
"some_class.py"の内容になります。
インポートしたgetmembers()を使用し、some_pkg1、some_pkg2内に定義されている関数を読み出します。
読み出した関数を、setattr()を使用して、自身の関数と定義させます。
# some_class.py
from inspect import getmembers, isfunction
from . import some_pkg1, some_pkg2
# 関数が定義されたパッケージを記述する
packages = [
some_pkg1,
some_pkg2
]
class SomeClass:
def __init__(self):
# 他パッケージ内の関数を読み出す
for package in packages:
pkg_funcs = getmembers(package, isfunction)
# 他パッケージの関数を自身のクラスに定義する
for pkg_func in pkg_funcs:
setattr(self.__class__, pkg_func[0], pkg_func[1])
あとは、some_pkg1・some_pkg2に任意の関数を定義します。
# some_pkg1.py
def pkg1_func1(self):
print('call: pkg1_func1')
def pkg1_func2(self):
print('call: pkg1_func2')
# some_pkg2.py
def pkg2_func1(self):
print('call: pkg2_func1')
SomeClassをインスタンス化すると、pkg1_func1()など、別モジュールに定義した関数を呼び出すことができます。
>>> from myproject.some_class import SomeClass
>>> sc = SomeClass()
>>> # some_pkg1.pyの関数を実行
>>> sc.pkg1_func1()
call: pkg1_func1
>>> # some_pkg2.pyの関数を実行
>>> sc.pkg2_func1()
call: pkg2_func1
Category: #コンピュータ