Passing objects around an event queue in Python
所以我对我正在做的事情有一个相对复杂的设置,解释如下:
这是Python。更多的是一个粗略的轮廓,但它涵盖了我所需要的一切。虽然下一个过程的功能是相同的,所以如果你想要的话,可以随时清理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | #timer event that runs every .1 second and processes events in a queue some_event_timer(): events.process_next() class Event_queue: def __init__(self): self.events = [] def push(self, event, parameters): self.events.insert(len(self.events), event, parameters) def process_next(self): event = self.pop(0) event[0](event[1]) class Foo: def __init__(self, start_value = 1): self.value = start_value def update_value(self, multiple): self.value *= multiple def return_bah(self) return self.value + 3 class Bar: def __init__(self, number1, number2): self.init = number1 self.add = number2 def print_alt_value(self, in_value): print in_value * (self.init + self.add) |
这是我所拥有的,但它说明了我的问题:做下面
1 2 3 4 5 6 7 8 9 10 11 | events2 = Event_queue2() foo1 = Foo(4) ----> foo1.value = 4 here bar1 = Bar(4, 2) events2.push(foo1.update_value,1.5) events2.push(bar1.print_alt_value,foo1.value) events2.push(bar.print_alt_value,foo1.return_bah()) events2.process_next() ----> should process update_value to change foo.value to 6 events2.process_next() ----> should process print_alt_value in bar class - expected 36 events2.process_next() ----> should process print_alt_value - expected 54 |
我最初期望我的输出是36 6*(4+2)
我知道为什么它不是,foo1.value和foo1.return_bah()作为一个被评估的参数被传递(正确的术语?).我真正想要的是将引用传递给变量或方法的引用,而不是让它在我将其放入事件队列时进行计算。
有人能帮我吗?
我试着去寻找,但我无法准确地拼凑出我想要的东西。为了得到我现在拥有的东西,我最初研究了这些线程:从字符串中调用模块的函数,该字符串的函数名为python
使用字符串调用python中的函数
但我不知道如何正确地支持来自该函数的参数,也不知道如何支持从这些函数传递另一个函数或变量引用。
我想至少对于方法调用,我可以将参数作为foo1.return.bah传递,并在进程_next方法中进行计算,但是我希望使用一种通用的方法来接受标准变量和方法调用,因为事件_队列将同时接受这两种调用。
谢谢你的帮助
更新编辑:
所以我遵循下面的建议,并且非常接近,但是:
好的,所以我遵循了您的队列建议,并且非常接近我想要的,但是我不完全理解关于多个函数的第一部分。
我也希望能用这个调用对象字典。例如:
1 2 3 | names = ["test1","test2"] for name in names: names_objs[name] = Foo(4) |
然后尝试通过lambda推动
1 2 | for name in names_list: events2.push(lambda: names_objs[name].update_value(2)) |
不起作用。当实际处理teh事件时,它只在任何名称的引用上运行,并且如果名称变量不再有效或已在函数外部修改,则它是错误的。这并不奇怪,但增加了一个:
1 | name_obj_hold = name_objs[name] |
然后推那个也没有。它同样只对上一次引用的名称进行操作。
有人能解释一下多重功能吗?恐怕我的头绕不动了。
基本上我需要对初始方法调用进行评估,比如:名字objs[名字]。一些func(这里有一些)获取正确的方法并与正确的类对象实例相关联,但在实际从事件队列调用之前,此处的某些内容不会被计算(无论是变量还是其他函数)。
不是传入函数来调用
1 2 3 4 5 6 7 8 9 10 11 12 13 | d = {"a":1} def p(val): print val def func1(): p(d["a"]) def call_it(func): func() call_it(func1) d["a"] = 111 call_it(func1) |
在
出于您的目的,您的队列将更改为:
1 2 3 4 5 6 7 | class EventQueue(object): def __init__(self): self.events = deque() def push(self, callable): self.events.append(callable) def process_next(self): self.events.popleft()() |
从队列前面弹出的
为了使用
1 2 3 4 5 6 7 8 9 10 11 | events2 = EventQueue() foo1 = Foo(4) bar1 = Bar(4, 2) events2.push(lambda: foo1.update_value(1.5)) events2.push(lambda: bar1.print_alt_value(foo1.value)) events2.push(lambda: bar1.print_alt_value(foo1.return_bah())) events2.process_next() events2.process_next() # 36.0 events2.process_next() # 54.0 |
编辑:
在这种情况下,您需要"捕获"变量中的值,该变量的作用域比循环更紧密。您可以使用普通函数和
1 2 3 4 | for name in names_list: def update(name): names_objs[name].update_value(2) events2.push(partial(update, name)) |