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

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

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

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

Q&A

解決済

2回答

211閲覧

リストに収納した関数を取り出して実行する際の処理

oglivie

総合スコア5

Python 3.x

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

0グッド

1クリップ

投稿2020/01/10 02:47

前提・実現したいこと

下のコードのように、python3.8でリストに多数の関数を収納して、そこからランダムに取り出して実行するプログラムを作成したいと考えています。
下のコードはいろいろ試行錯誤してうまく動くのですが、17行目のcul0の引数selfが必要な理由がわかりません。selfがないとエラーになります。

普通にadd()とやるときは引数はいらないのに、リストから取り出した関数を実行するときだけ引数が必要なのは何故なのでしょう?

該当のソースコード

python3.8

1import random as r 2 3class Test: 4 5 num=1 6 7 def add(self): 8 self.num += 1 9 10 def dif(self): 11 self.num -= 1 12 13 cul=[add,dif] 14 15 def rand_cul(self): 16 r.shuffle(self.cul) 17 self.cul[0](self) 18 return self.num

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

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

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

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

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

guest

回答2

0

まず前提を確認しておきますが、そのculはいわゆるクラス変数になります。

また、クラスのスコープ内で参照できるadd,difは「ただの関数」になり、インスタンスメソッドとしては取り出せません。インスタンス化されていないので当然なのですが。

インスタンスメソッドの場合は自動的にselfを与えて呼び出してくれますが、ただの関数にはこの機構は機能しません。なので、明示的にselfを与えて呼び出してあげる必要があるということですね。


そんな訳のわからない状況にはしたくないので、すべてインスタンス変数として扱う前提で書くとこうなります。numも直しておきます。

python

1import random as r 2 3class Test: 4 def __init__(self): 5 self.num=1 6 self.cul=[self.add, self.dif] 7 8 def add(self): 9 self.num += 1 10 11 def dif(self): 12 self.num -= 1 13 14 def rand_cul(self): 15 r.shuffle(self.cul) 16 self.cul[0]() 17 return self.num 18

特段クラス変数にする必要がなければ、この方がすっきりするのではないでしょうか。

投稿2020/01/10 03:00

hayataka2049

総合スコア30933

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

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

0

ベストアンサー

hayataka2049 さんの回答で解決すると思いますが、ちょっとしたアドバイスを。
変数名や関数名に意味を込めましょう。名前はできるだけ省略せずに。
メソッドで return self すればメソッドチェーンできます。
__str__ メソッドを作っておけば printで文字列出力するときに呼び出してくれます。

python

1import random as r 2 3class Calculator: 4 5 def __init__(self): 6 self.value = 0 7 self.functions = self.increment, self.decrement 8 9 def __str__(self): 10 return str(self.value) 11 12 def increment(self): 13 self.value += 1 14 return self 15 16 def decrement(self): 17 self.value -= 1 18 return self 19 20 def random(self): 21 r.choice(self.functions)() 22 return self 23 24print(Calculator().random().random().random().random().random())

投稿2020/01/10 03:16

編集2020/01/10 03:17
shiracamus

総合スコア5406

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問