pythonにおいて、とあるclass Aから別のclass Bの関数を実行したい場合。
class Aにclass Bのインスタンスを渡す用の関数(以下例でいえばstate.XX_object(X)の箇所)を用意して、インスタンスをselfに代入し、class Aの中でもclass Bの関数群を実行できるようにしています。
保守性や可読性の観点から、そのような記述方法で良いのか、ベストプラクティスは無いのかと探しております。
以下はコードの例です。
例えば、TkinterのGUIアプリを作ると想定します。
画面生成を制御しやすいように、transitionsパッケージを導入して、状態遷移から画面を制御します。
また、操作時に音が鳴るようにしたいので、音再生の関数群のmusicplay.pyも用意するとします。
動作例としては、
0. 画面のとあるボタンAが押される、
0. transition.pyモジュールのdef action_create_a(self)が実行される。状態がapp_aになる
0. application.pyモジュールのdef create_a_frame(self)が実行される。画面がAになる。
0. musicplay.pyのdef touch_music_play(self)が実行されて音が出る。
というような流れで動作します。
【当質問の部分1】と【当質問の部分2】とコメントアウトしている部分が、前述のclass Aの中でもclass Bの関数群を実行できるようにしている部分です。
main.py
python
1from module import application 2from module import transitions 3from module import musicplay 4 5if __name__ == '__main__': 6 7 # 状態遷移インスタンス生成 8 state = transitions.StateMachine('start_state') 9 10 # インスタンス生成 11 app = application.App(master=tk.Tk()) 12 ms = musicplay.Music() #音再生 13 14 # ステートマシンに各オブジェクトを渡す【当、質問の部分1】 15 state.get_app_object(app) #画面描画 16 state.get_music_object(ms) #音再生 17 18 # 画面描画プログラム起動 19 app.mainloop() 20
transitions.pyモジュール
Python
1from transitions import Machine 2 3class StateMachine(object): 4 5 # ステータスの定義 6 states = ['start', 'app_a', 'app_b', 'app_c'] 7 8 def __init__(self): 9 self.machine = Machine(model=self, states=StateMachine.states, initial='start', auto_transitions=False) 10 11 # トリガーの定義 12 self.machine.add_transition(trigger='create_a', source='start', dest='app_a', after='action_create_a') 13 self.machine.add_transition(trigger='create_b', source='app_a', dest='app_b', after='action_create_b') 14 self.machine.add_transition(trigger='create_c', source='app_b', dest='app_c', after='action_create_c') 15 16 # actionの設定 17 def action_create_a(self): 18 self.app.create_a_frame() 19 self.ms.touch_music_play() 20 21 def action_create_b(self): 22 self.app.create_b_frame() 23 self.ms.touch_music_play() 24 25 def action_create_c(self): 26 self.app.create_c_frame() 27 self.ms.touch_music_play() 28 29 ''' 30 他クラスのインスタンス取得関数【当、質問の部分2】 31 ''' 32 # applicationインスタンス取得 33 def get_app_object(self, app): 34 self.app = app 35 36 # musicインスタンス取得 37 def get_music_object(self, ms): 38 self.ms = ms 39
application.pyモジュール
python
1import tkinter as tk 2from tkinter import ttk 3 4class App(tk.Frame): 5 def __init__(self, master): 6 7 #中略 8 9 def create_a_frame(self): 10 #画面A生成プログラム 11 12 def create_b_frame(self): 13 #画面B生成プログラム 14 15 def create_c_frame(self): 16 #画面C生成プログラム 17
musicplay.pyモジュール
python
1import pygame.mixer 2 3class Music(): 4 # mixerモジュールの初期化 5 pygame.mixer.init() 6 7 def touch_music_play(self): 8 pygame.mixer.music.load('./media/touch.mp3') 9 pygame.mixer.music.play() 10
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。