所以我对我正在研究的内容进行了相对复杂的设置,解释如下:
这是python.更粗略的轮廓,但它涵盖了我需要的一切.虽然下一个功能的过程是相同的,但如果你愿意,可以随意清理它.
#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)
这是我所拥有的准系统,但它说明了我的问题:
做下面的事情
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()作为一个评估参数传递(正确的术语?).
我真正想要的是将引用传递给变量或方法的引用,而不是在我将它放入事件队列时进行评估.
谁能帮我.
我试着搜索,但我无法拼凑出我想要的东西.
为了得到我现在拥有的东西我最初看了这些线程:
Calling a function of a module from a string with the function’s name in Python
Use a string to call function in Python
但我没有看到如何正确支持参数或如何支持从那些传递另一个函数或引用变量.
我想至少对于方法调用,我可以将参数作为foo1.return.bah传递并在process_next方法中进行评估,但我希望有一种通用的方法可以接受标准变量和方法调用,因为event_queue将拿两个.
感谢您的帮助
更新编辑:
所以我按照下面的建议,并且非常接近,但是:
好的,所以我按照你的队列建议并且非常接近我想要的,但我并不完全理解关于多个功能的第一部分.
我希望能够用这个来调用对象字典.
例如:
names = ["test1", "test2"]
for name in names:
names_objs[name] = Foo(4)
然后当试图通过lambda推
for name in names_list:
events2.push(lambda: names_objs[name].update_value(2))
不起作用.当teh事件实际被处理时,它只在name_objs [name]引用上运行,如果name变量不再有效或者在函数外部被修改,则它是错误的.
这实际上并不奇怪,但添加了:
name_obj_hold = name_objs[name]
然后推动那也没有.它再次只能在最后引用的name_obj_hold上运行.
有人可以澄清多个功能的事情.我担心我的头很难缠绕它.
基本上我需要初始方法调用评估,所以像这样:
names_objs [name] .some_func(#something in here#)
获取正确的方法并与正确的类对象实例相关联,但是#eomething in here#不会被评估(无论是变量还是其他函数),直到它实际从事件队列中调用.
最佳答案 不是传入调用func1的函数和应该传递给函数的参数,而是传入一个函数func2,该函数使用应该传入的参数调用func1.
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)
在func1中,直到func1实际执行才会计算d [“a”].
出于您的目的,您的队列将更改为:
class EventQueue(object):
def __init__(self):
self.events = deque()
def push(self, callable):
self.events.append(callable)
def process_next(self):
self.events.popleft()()
collections.deque从队列前面弹出比列表更快.
要使用EventQueue,您可以使用lambdas进行快速匿名功能.
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
对于编辑:
在这种情况下,您需要“捕获”一个比循环更严格的变量中的值.您可以使用普通函数和partial()
来实现此目的.
for name in names_list:
def update(name):
names_objs[name].update_value(2)
events2.push(partial(update, name))