質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

649閲覧

pythonで動的に関数を呼び出す

sirokuma5296

総合スコア17

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

2クリップ

投稿2020/08/26 10:20

編集2020/08/26 10:21

pythonでファイルに書かれている関数を動的に呼び出すということをやりたいと考えています。

動的に関数を呼び出すものとして locals/globals があるようですが、あくまでソースの中にある関数を呼び出せるというものだと思っています。(間違っていたらごめんなさい)

getattr()を使えばできそうな感じもしているのですが、できていません。

アプリから取得できる情報として、関数を記述しているファイル名(フルパス)・クラス名・関数名の3つがわかれば、できそうな気がしています。
やり方が分かる方がいましたら、ご回答お願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

otn

2020/08/26 10:28

具体的にどういうことがしたいのでしょうか?
sirokuma5296

2020/08/26 10:35

作成したアプリの入力情報をチェックする処理を外出しにして、簡単にチェック処理を変えられるようにしたいというのが目的です。 やりたいことは、 1.アプリ起動時に設定ファイルを読み込み、チェック処理がかかれているファイル名・クラス名・関数名を取得する。 2.外から入力情報が入ってきたときに、1.で読み込んだ関数を呼び出し、入力情報の正当性をチェックする。 回答になっていますでしょうか?
otn

2020/08/26 10:45

もう少し具体的におねがいします。コードレベルで。 設定ファイル上にプログラムを書きたいと言うことですか?
sirokuma5296

2020/08/26 11:44

以下のような記述をしたファイルを読み込み、特定の関数を実行するイメージです。 -------------------- filepath : /home/testuser/aplcheck.py classname: check funcname: input_check -------------------- コードレベルでかけれておらずすみません。。
guest

回答2

0

目的が、「入力情報をチェックする処理を外出しにして、簡単にチェック処理を変えられるようにしたい」 ということですし、そもそもチェック処理を呼び出す側は、任意の関数を任意の引数で呼び出せるようにするあまり現実的ではないと思うので、

  • チェック処理のクラス/関数/引数は固定する。
  • そのチェック処理を別モジュール(ファイル)にして、importする

のが適当ではないでしょうか。、

投稿2020/08/26 11:13

TakaiY

総合スコア13790

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sirokuma5296

2020/08/26 11:27

コメントありがとうございます。 TakaiYさんのおっしゃるとおり、上記の条件でもやりたいことはできますね。 自由度をあげることだけがよいとは限らないですね。 勉強になります。
guest

0

ベストアンサー

importlib と getattr() を使えば実現できます。

importlib --- import の実装 — Python 3.8.5 ドキュメント

python

1import importlib 2 3module_name = "a" 4func_name = "func_a" 5 6module = importlib.import_module(module_name) 7func = getattr(module, func_name) 8 9func() # a.func_a

a.py

python

1def func_a(): 2 print("a.func_a")

b.py

python

1def func_b(): 2 print("b.func_b")

追記

python

1import importlib.util 2from pathlib import Path 3 4module_path = "/data/notebook/test/a.py" 5class_name = "MyClass" 6func_name = "func" 7 8module_path = Path(module_path) 9spec = importlib.util.spec_from_file_location(module_path.stem, module_path) 10module = importlib.util.module_from_spec(spec) 11spec.loader.exec_module(module) 12 13MyClass = getattr(module, class_name) 14 15inst = MyClass() 16func = getattr(inst, func_name) 17 18func() # func called

/data/notebook/test/a.py

python

1class MyClass: 2 def func(self): 3 print("func called")

投稿2020/08/26 10:46

編集2020/08/26 11:27
tiitoi

総合スコア21956

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sirokuma5296

2020/08/26 11:02

ご回答ありがとうございます。 提示いただいたソースコードは意図した通り動くことが分かりました。 こちらで動作確認したところ、カレントディレクトリにa.pyがある場合は、動作したのですが、他のディレクトリにある場合は、エラーになってしまいました。(当たり前ですが) 別のディレクトリにあるファイルの関数を実行した場合は、カレントディレクトリを一時的に移動するなどの手順を踏むのがよいでしょうか?
tiitoi

2020/08/26 11:12

> 関数を記述しているファイル名(フルパス)・クラス名・関数名の3つがわかれば、できそうな気がしています。 この情報は具体例にどのような形で与えられるかサンプルを記載していただけますか
tiitoi

2020/08/26 11:22

一応、モジュール名、ファイルパス、関数名が与えられている場合のバージョンも追記しました。
sirokuma5296

2020/08/26 11:22

> この情報は具体例にどのような形で与えられるかサンプルを記載していただけますか このようなイメージです。よろしくお願いします。 /etc/opt/testapl/conf.yml(このファイルのパスは把握している前提) -------------------- filepath : /home/testuser/aplcheck.py classname: check funcname: input_check --------------------
sirokuma5296

2020/08/26 11:25

回答いただきありがとうございます。 すぐに確認作業ができる状況にないので、改めて確認したうえで連絡させていただきます。
sirokuma5296

2020/08/26 23:24

提示いただいたコードで意図した動きができたことを確認できました。 importlibやgetattrなどのパーツは調べるとでてきたのですが、組み合わせ書くところができてないところがまだまだです。 大変助かりました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問