Pythonic管理多个回调的方法

时间:2013-07-06 21:58:20

标签: python sublimetext2

我正在为Sublime Text 2编写一个小插件。工作流程要求我多次提示用户以获得一系列答案。

我正在使用show_input_panel来获取输入,我正在定义一个函数来收集每个答案。

以下是代码示例:

import sublime, sublime_plugin

class SampleCommand(sublime_plugin.TextCommand):

    #############################
    # Main
    #############################

    def run(self, edit):
        self.edit = edit

        self.window = sublime.active_window()

        # first prompt
        self.window.show_input_panel('First question', '', self.on_first_answer, None, None)

    #############################
    # Async Handlers
    #############################

    def on_first_answer(self, answer_a):
        self.answer_a = answer_a
        self.window.show_input_panel('Second question', '', self.on_second_answer, None, None)

    def on_second_answer(self, answer_b):
        self.answer_b = answer_b
        self.window.show_input_panel('Third question', '', self.on_third_answer, None, None)

    def on_third_answer(self, answer_c):
        answers = self.answer_a + self.answer_b + answer_c
        sublime.message_dialog('Your answers: ' + answers)

我是Python的新手,所以我想知道是否有更好的方法来组织这些多个回调。

在JavaScript中,我开始使用匿名闭包,这将使我无法将每个答案存储在对象上。 当闭包不够时,我会尝试承诺。

在Python中管理类似场景的最佳方法是什么?

1 个答案:

答案 0 :(得分:1)

generator.send对于这类事情非常有用:

import sublime

def prompt_sequence(g):
    def progress(result):
        try:
            progress.caption, progress.initial_text = g.send(result)
            sublime.active_window().show_input_panel(
                progress.caption,
                progress.initial_text,
                progress, None, None
            )
        except StopIteration:
            pass

    progress(None)

def foo():
    first_answer = yield ('First question', '')
    second_answer = yield ('Second question', '')
    third_answer = yield ('Thirdquestion', '')

    sublime.message_dialog('Your answers: ' + answers)

prompt_sequence(foo())

或写另一种方式(可能不起作用):

def self_referencing(gen_func):
    @functools.wraps(gen_func)
    def wrapped(*args, **kwargs):
        g = gen_func(lambda: g, *args, **kwargs)
        return g
    return wrapped



class SampleCommand(sublime_plugin.TextCommand):
    @self_referencing
    def get_things(gen_self, self):
        sublime.active_window().show_input_panel(
            'First question', '',
            gen_self().send, None, None
        )
        result_a = yield
        sublime.active_window().show_input_panel(
            'Second question', '',
            gen_self().send, None, None
        )
        result_b = yield
        sublime.active_window().show_input_panel(
            'Third question', '',
            gen_self().send, None, None
        )
        result_c = yield