Передать дополнительные аргументы с помощью функции обратного вызова
В следующем примере (взятом отсюда: http://urwid.org/tutorial/index.html) показано, как передать значения ключей в функцию обратного вызова show_or_exit
,
import urwid
def show_or_exit(key):
if key in ('q', 'Q'):
raise urwid.ExitMainLoop()
txt.set_text(repr(key))
txt = urwid.Text(u"Hello World")
fill = urwid.Filler(txt, 'top')
loop = urwid.MainLoop(fill, unhandled_input=show_or_exit)
loop.run()
Как я могу передать другой аргумент show_or_exit
с этим обратным вызовом, который зависит от состояния системы, это будет что-то вроде этого?
...: param_val = 4
...:
...: def my_fun():
...: #do something
...: return param_val
...:
...: def show_or_exit(key, param_val):
...: if key in ('q', 'Q'):
...: raise urwid.ExitMainLoop()
...: txt.set_text(repr(key))
...: do_something(param_val)
...:
...: txt = urwid.Text(u"Hello World")
...: fill = urwid.Filler(txt, 'top')
...: loop = urwid.MainLoop(fill, unhandled_input=show_or_exit)
...: loop.run()
1 ответ
Итак, есть несколько способов сделать это. Вы можете использовать глобальные переменные, но я предполагаю, что вы, вероятно, задаете этот вопрос, потому что вы хотите лучший способ сделать это (плюс, глобальные переменные были бы неуклюжи, чтобы изменить состояние в любом случае).
Для небольших программ, таких как в этом примере, одним из методов может быть использование одного глобального объекта, хранящего состояние:
import urwid
from functools import partial
class State(object):
param1 = 1
param2 = 'ola'
def __repr__(self):
return 'State(param1={}, param2={})'.format(self.param1, self.param2)
def show_or_exit(app_state, key):
if key in ('q', 'Q'):
raise urwid.ExitMainLoop()
app_state.param1 += 1
txt.set_text('key: {!r} state: {!r}'.format(key, app_state))
txt = urwid.Text(u"Hello World")
fill = urwid.Filler(txt, 'top')
app_state = State()
callback = partial(show_or_exit, app_state)
loop = urwid.MainLoop(fill, unhandled_input=callback)
loop.run()
Я сохранил этот пример минимальным для целей иллюстрации, но этот класс State выиграл бы ОЧЕНЬ много от использования библиотеки attrs. Настоятельно рекомендуется!:)
Для более сложных программ я бы предложил создавать собственные виджеты, поддерживающие события обратного вызова, и управлять состоянием отдельно: вы можете увидеть пример реализации этого в этой пасьянсе.