首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在pytransitions中处理多个对象

在pytransitions中处理多个对象
EN

Stack Overflow用户
提问于 2021-09-07 15:40:31
回答 2查看 63关注 0票数 1

https://github.com/pytransitions/transitions

我尝试使用文档中的batman = NarcolepticSuperhero("Batman")示例。但是假设我们有100个蝙蝠侠要处理,我的方法是创建每个蝙蝠侠对象的列表,并使用循环分别跟踪它们的状态。我想这是非常幼稚的。

有没有人能提出一些有效的解决方案。

谢谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-09-10 08:19:28

假设所有NarcolepticSuperheros的行为都是一样的,我建议对所有的“蝙蝠侠”使用一个Machine,而不是多次实例化NarcolepticSuperhero。通过这种方式,您可以使用Machine.dispatch在所有型号上触发事件,而不是遍历超级英雄列表(在引擎盖下,Machine也只是在型号列表中循环)。我稍微压缩了一下前面提到的例子(所有的转换都在一个列表中),删除了绑定到NarcolepticSuperheros的机器并引入了一个SuperheroDen。关于状态检查,您可以使用字典来跟踪当前有多少英雄处于何种状态。我在NarcolepticSuperhero中添加了一个hero_log,每次英雄更改状态时,它都会首先注销当前状态,然后使用新状态登录。

代码语言:javascript
复制
from transitions import Machine
from collections import  defaultdict
import random


class NarcolepticSuperhero(object):

    hero_log = defaultdict(list)

    def __init__(self, name):
        self.name = name
        self.kittens_rescued = 0

    def update_journal(self):
        self.kittens_rescued += 1

    @property
    def is_exhausted(self):
        return random.random() < 0.5

    @staticmethod
    def change_into_super_secret_costume():
        print("Beauty, eh?")

    def log_out(self):
        self.hero_log[self.state].remove(self)

    def log_in(self):
        self.hero_log[self.state].append(self)


class SuperheroDen(Machine):
    states = ['asleep', 'hanging out', 'hungry', 'sweaty', 'saving the world']
    transitions = [
        ['wake_up', 'asleep', 'hanging out'],
        ['work_out', 'hanging out', 'hungry'],
        ['eat', 'hungry', 'hanging out'],
        ['nap', '*', 'asleep'],
        dict(trigger='distress_call', source='*', dest='saving the world', before='change_into_super_secret_costume'),
        dict(trigger='complete_mission', source='saving the world', dest='sweaty', after='update_journal'),
        dict(trigger='clean_up', source='sweaty', dest='asleep', conditions=['is_exhausted']),
        ['clean_up', 'sweaty', 'hanging out'],
    ]

    def __init__(self):
        super().__init__(model=[NarcolepticSuperhero('Clone warrior') for i in range(100)],
                         states=self.states,
                         transitions=self.transitions,
                         # tell each model to 'log_out' right before state change
                         before_state_change='log_out',
                         # and to 'log_in' right after
                         after_state_change='log_in',
                         initial='asleep')
        # since our super heroes are asleep (and 'spawn' in their state), we have to log them in the first time
        for model in self.models:
            NarcolepticSuperhero.hero_log[self.initial].append(model)


machine = SuperheroDen()
# trigger event 'wake_up' on all models
machine.dispatch('wake_up')
assert len(NarcolepticSuperhero.hero_log['asleep']) == 0
assert len(NarcolepticSuperhero.hero_log['hanging out']) == 100
for i in range(10):
    machine.models[i].work_out()
assert len(NarcolepticSuperhero.hero_log['hanging out']) == 90
assert len(NarcolepticSuperhero.hero_log['hungry']) == 10
assert machine.models[0] in NarcolepticSuperhero.hero_log['hungry']
票数 1
EN

Stack Overflow用户

发布于 2021-09-08 02:50:40

你的建议在我看来是合理的。

代码语言:javascript
复制
heros = [NarcolepticSuperhero(f"Batman{i:02d}")
         for i in range(100)]

然后循环遍历它们,或者使用一个while True:循环,该循环休眠片刻,然后随机挑选一个英雄。无论哪种方式,你都会有一个英雄,你可以在上面触发一些新的过渡。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69091089

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档