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

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

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

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

Python

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

Q&A

解決済

4回答

8148閲覧

defの関数名に変数を使って、for文など変数を使って綺麗な形で呼び出したい。

Aki1000

総合スコア78

Python 3.x

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

Python

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

0グッド

0クリップ

投稿2021/04/16 18:31

編集2021/04/16 20:04

Python

1 2class test: 3 def test_1(self): 4 print(1) 5 6 def test_2(self): 7 print(2) 8 9 def test_3(self): 10 print(3) 11 12 def test_4(self): 13 print(4) 14 15 16 17if __name__ == '__main__': 18 T = test() 19 T.test_1() 20 T.test_2() 21 T.test_3() 22 T.test_4() 23

このT.test_i()とかいちいち変数名を書いている部分をfor文で呼び出すのに、

Python

1if __name__ == '__main__': 2 T = test() 3 for i in range(4): 4 trgfunc = "T.test_" + str(i+1) + "()" 5 eval(trgfunc)

としました。これで一応動くのですが、trgfunc = "T.test_" + str(i+1) + "()"
とか、いまいち綺麗じゃないのですが、こんなものでしょうか?
変数を使っての関数の呼び出し方、もう少し綺麗なやり方はないでしょうか?

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

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

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

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

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

quickquip

2021/04/17 03:33

実際のコードでもtest_で始まる名前なのか? 何をするコードのなのか(なんのためのclassなのか)? あたりが書かれてないと一般論として”それはよくない"という回答が集まりやすくなってしまいます。 XY問題とはなんですか https://ja.meta.stackoverflow.com/questions/2701/
guest

回答4

0

関数名に変数を使うというのは考え方からして間違ってます(にもう一票)。

これは本当に質問者さんの手元のコードは test_1 みたいなことになっているのでしょうか?

python

1class test: 2 def test(self, i): 3 print(i)

とするのがよかったのであって、そうせずに関数名に1とか2とかが入っている合理的な理由がほんの少しでも存在するとは思えません。
(質問に書かれていない全然違う事情があるとしても、その事情の方を質問するべきだろうと思えます)


(追記)

目的が曖昧なのですが、inspectモジュールでメソッドを列挙させる方がメソッドを追加した時に実行する方の変更が要らなくて便利だと思うんですよね。

python

1if __name__ == '__main__': 2 import inspect 3 4 t = Test() 5 for name, method in inspect.getmembers(t, inspect.ismethod): 6 if name.startswith('test_'): 7 method()

投稿2021/04/16 22:49

編集2021/04/17 09:13
quickquip

総合スコア11235

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

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

Aki1000

2021/04/17 05:30

知りたいのは、関数に変数を使用して呼び出す方法でした。 たくさん関数があって、かつ、増える予定で、いちいちその名前を作って呼び出すのはちょっと……。 それで、for文で呼び出したら数行で済むじゃ無いか、と。
quickquip

2021/04/17 08:27 編集

なぜたくさんの関数を全部呼び出さなきゃいけないなんてことが発生するのか? という方に目に行きます。 たくさんメソッドがあって全部呼び出したいというシチュエーションはユニットテストなどではありえるでしょうが、それはユニットテスト用のライブラリを使いましょう、という方が自然です。 > たくさん関数があって、かつ、増える予定で、いちいちその名前を作って呼び出すのはちょっと……。 は理解できますが「for文で関数名を作って呼び出す」というのは解決策としてちょっと……と感じました。 典型的なXY問題の質問という印象です。
guest

0

メソッド名を合成するための基底クラスを作ってみました。

python

1class Method: 2 def call2(self, first, second, *args, **kwargs): 3 type(self).__dict__[f'{first}{second}'](self, *args, **kwargs)

このクラスを基底クラスとすると以下のことができます。

python

1>>> class test(Method): 2... def test_1(self): 3... print(1) 4... def test_2(self): 5... print(2) 6... def test_3(self): 7... print(3) 8... def test_4(self): 9... print(4) 10... 11>>> T = test() 12>>> 13>>> T.call2("test_", 1) 141 15>>> 16>>> for i in range(4): 17... T.call2("test_", i+1) 18... 191 202 213 224

投稿2021/04/17 00:27

ppaul

総合スコア24670

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

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

0

そもそも関数名に変数を使うというのは考え方からして間違ってます
関数のリストでも作ればどうでしょう

投稿2021/04/16 21:56

y_waiwai

総合スコア88042

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

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

xail2222

2021/04/16 22:13

質問者ではないですが、関数のリストはどうやってつくるのですか? classのメソッドではないならリストにする方法はわかるのですが
Aki1000

2023/05/10 08:22

当時、関数のリストをつくるの意味が分かっていませんでした。 pythonでは関数そのものをリスト変数としてリストの中に格納できる。 関数をリストに代入して、一番目二番目と呼び出せば今となってはこれが一番良い気がします。
guest

0

ベストアンサー

ネット調べたら書いてあった。

python

1if __name__ == '__main__': 2 T = test() 3 for i in range(1,5): 4 getattr(T,'test_' + str(i))() 5

リンク

(追記)
呼び出す関数をリストにすると言っても
クラスなので、インスタンスの実体を作るたびにリストに格納して呼び出すのは
非効率な感じがします。

また関数で分けずに一まとめにして、パラメーターを使って処理を分ける
と言うより、処理を分けた方が明瞭化されると思うし

呼び出す関数を振り分ける関数を一つ追加する。というのは
関数の名前で処理を示している場合に、関数を指すパラメータは何がいいのかということもあるし

と、私の拙い知識で考えてると、確かに実際の用途によって何が最適かは変わってくるかとは思いますが
クラスの関数の呼び出しはgetattrでもいいんじゃないかと思いました。

投稿2021/04/16 20:32

編集2021/04/16 23:30
xail2222

総合スコア1508

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問