LoginSignup
18
16

More than 5 years have passed since last update.

Pythonで動的にメソッドを呼ぶ

Last updated at Posted at 2014-03-14

基本かもしれないですけど。

なんで今更?ってtornado使ってWebSocketでやりとりしていた時

Javascriptでコールバックメソッド名送る
→ tornadoで指定されたメソッドを実行して、Javascriptにコールバック関数名送る
→ Javascriptで指定されたコールバック関数を実行する

ってやりたくて文字列からメソッドを呼び出しをしたかったのです。

まずはJavascript、WebSocket接続してtornado側の呼び出しメソッド名とその他のパラメータを送ります。
パラメータはJSONで送ってます。

var ws = new WebSocket('ws://server/ws');
var p = {};
// callbackメソッド名
p['callback'] = 'wake_up';
// その他のパラメータ
p['msg'] = 'Wake Up!!!!';
ws.send(JSON.stringify(p));
ws.onmessage = function(e) {
    var data = JSON.parse(e.data);
    console.log(data['message']);
};

tornado側、on_messageのgetattrが今回の表題のメイン部分です。

app.py
from tornado import ioloop,web,websocket
import json
# callbackクラス
from callback import Callback

class WSHandler(websocket.WebSocketHandler):
    # メッセージが来た時
    def on_message(self, message):
        data = json.loads(message)
        # Callbackクラスのインスタンス作成
        cb = Callback(data)
        # メソッド呼び出し
        result = getattr(cb, data['callback'])()

        # Javascriptに返す値
        return_value = {}
        return_value['message'] = result

        # WebSocketでメッセージ送信
        self.write_message(json.dumps(return_value))

handlers = [
    (r'/ws', WSHandler),
]

settings = dict(
    debug = False,
)

app = web.Application(handlers, **settings)
app.listen(sys.argv[1])
ioloop.IOLoop.instance().start()

呼び出されるメソッドです。

callback.py
class Callback(data):
    def __init__(self, data):
        self.data = data

    def wake_up(self):
        return self.data['msg']

これでブラウザのコンソールに'Wake Up!!!!’と表示されるはずです。

getattrの使い方は以下の通りです。詳細は公式ドキュメントに委ねます。

cb = Callback(data)
result = cb.wake_up()

# 上記は下記コードと同じです
result2 = getattr(cb, 'wake_up')()

# 因みに以下のようにやると返り値が返らずオブジェクトが代入されます
result3 = getattr(cb, 'wake_up')

最初上のresult3のようにやってしまい???ってなりましたが、考えてみればですよね〜ってなりました。。。

2013-03-15追記
微妙に間違いを修正しました。
失礼しました。

18
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
16