Библиотека python переходов: Как передать argumnets на переход? - PullRequest
0 голосов
/ 25 марта 2020

Следуя документации на github, не очевидно, как создать параметризованный переход.

Они определяют переходы как

self.machine.add_transition(trigger='wake_up', source='asleep', dest='hanging out')

И я хочу что-то вроде

self.machine.add_transition(trigger='wake_up_parameterized', source='asleep', dest='hanging out', ...)

где ... каким-то образом передать требуемые параметры wake_up_parameterized потребуется.

Использование будет

batman.wake_up_parameterized(my_param1, my_param2)

Поддерживается ли это в Transisions?

Если нет, то как мне go обойти это? Кажется довольно основа c.

1 Ответ

1 голос
/ 26 марта 2020

В документации, на которую вы ссылаетесь, говорится:

Иногда вам необходимо передать функциям обратного вызова, зарегистрированным при инициализации машины, некоторые данные, которые отражают текущее состояние модели. Transitions позволяет вам делать это двумя различными способами.

Во-первых (по умолчанию), вы можете передавать любые позиционные или ключевые аргументы непосредственно в триггерные методы (созданные при вызове add_transition () [...]. может передать в триггер любое количество аргументов, которые вам нравятся. У этого подхода есть одно важное ограничение: каждая функция обратного вызова функция, инициируемая переходом состояния, должна иметь возможность обрабатывать все аргументы. Это может вызвать проблемы, если каждый из обратных вызовов ожидает несколько разных данных.

При изменении состояний работа может выполняться в обратных вызовах . transitions предлагает несколько случаев, когда могут быть вызваны обратные вызовы. Из документации:

Callback Execution Order

Наиболее распространенный вариант использования - определить, должен ли переход происходить на основе переданных параметров. Правильное расположение для этого обратного вызова: conditions Если нужно проверить более одного перехода, но предварительная обработка данных несколько интенсивна, prepare c может быть использовано вместо Сейчас давайте предположим, что должен быть проверен только один переход.

from transitions import Machine
import random


class Superhero:

    def world_is_in_danger(self, chocolate_bars, *args, **kwargs):
        return chocolate_bars < 3

    def business_hours(self, time, *args, **kwargs):
        return 9 < time < 17

    def restock(self, chocolate_bars, *args, **kwargs):
        new_stock = chocolate_bars + random.randrange(1, 4, 1)  # heroes cannot carry more than 3 bars at a time
        print(f"I am {self.state} and went to the store at {time}. The stock is now {new_stock}.")


hero = Superhero()
machine = Machine(model=hero, states=['resting', 'awake'], initial='resting')
machine.add_transition('call_for_help', 'resting', 'awake',
                       conditions=['world_is_in_danger', hero.business_hours],
                       after='restock')
hero.call_for_help(chocolate_bars=10, time=5)  # everything looks good
assert hero.state == 'resting'  # hero isn't moving a bit
hero.call_for_help(chocolate_bars=2, time=8)  # we are about to run out! but it's too early...
assert hero.is_resting()
hero.call_for_help(chocolate_bars=1, time=10, weather='sunny')  # someone must help us!
# >>> I am awake and went to the store at 10. The stock is now 3.
assert hero.is_awake()

Как упоминалось в документации, каждый параметр, переданный в функцию триггера, будет передан всем зарегистрированным обратным вызовам. Стандартный способ регистрации обратных вызовов - передать их в add_transition. Мы передали два обратных вызова conditions: один в виде строки, которая является стандартным способом сделать это, и один в качестве ссылки на функцию. Передача обратных вызовов в виде строк предполагает, что наша модель (наш герой) имеет метод (или будет иметь метод во время вызова) с этим именем. Ссылка на функцию не должна присваиваться рассматриваемой модели. Мы также зарегистрировали один обратный вызов для after, который будет вызываться, когда будет выполнен переход. Если мы оценим hero.state в этом обратном вызове, он уже установлен на awake. Добавив *args и **kwargs к нашим функциям обратного вызова, мы убедились, что обратные вызовы достаточно гибки, чтобы иметь дело с переменным количеством передаваемых параметров и учитывать только соответствующую информацию.

...