我已经创建了一个类,它可以接受带有一组参数的函数。我希望每次事件处理程序发出信号时都运行传递的函数。
我在下面附加了一个代码,当我传递一个fun2
它没有参数但没有fun1
时,它将运行。我能对下面的代码提出什么建议吗?如果省略fun1
中的return语句,则会得到一个'str' object is not callable
错误。
>>> TimerTest.main()
function 1. this function does task1
my function from init from function1
my function in start of runTimerTraceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Program Files (x86)\IronPython 2.7\TimerTest.py", line 57, in main
File "C:\Program Files (x86)\IronPython 2.7\TimerTest.py", line 25, in runTime
r
TypeError: str is not callable
import System
from System.Timers import (Timer, ElapsedEventArgs)
class timerTest:
def __init__ (self, interval,autoreset, fun):
self.Timer = Timer()
self.Timer.Interval= interval
self.Timer.AutoReset = autoreset
self.Timer.Enabled = True
self.myfunction = fun
def runTimer(self):
print 'my function in start of runTimer', self.myfunction ()
self.Timer.Start()
def OnTimedEvent (s, e):
print "The Elapsed event was raised at " , e.SignalTime
print 'printing myfunction...', self.myfunction()
self.myfunction()
self.Timer.Elapsed += OnTimedEvent
def stopTimer(self):
self.Timer.Stop()
self.Timer.Dispose= True
def fun1(a,b):
print 'function 1. this function does task1'
return 'from function1'
def fun2():
print 'Function 2. This function does something'
print 'Test 1...2...3...'
return 'From function 2'
def main():
a = timerTest(1000, True, fun1(10,20))
a.runTimer()
b= timerTest(3000,True,fun2)
b.runTimer()
if __name__ == '__main__':
main()
我正在学习Python,如果我的问题是基本的,我很抱歉。
要更改间隔,我使用添加到timerTest类的stopTimer方法停止计时器:
def stopTimer(self):
self.Timer.Stop()
我使用新的用户输入调用runTimer方法,我根据Paolo Moretti的建议修改了该方法:
def runTimer(self, interval,autoreset,fun,arg1, arg2, etc.):
self.Timer.Interval= interval
self.Timer.AutoReset = autoreset
myfunction = fun
my_args = args
self.Timer.Start()
def OnTimedEvent (s, e):
print "The Elapsed event was raised at " , e.SignalTime
myfunction(*my_args)
self.Timer.Elapsed += OnTimedEvent
每当按下命令按钮时,将调用以下方法:
requestTimer.runTimer((self.intervalnumericUpDown.Value* 1000),True, function, *args)
我不明白为什么停止计时器并发送请求会导致runTimer方法多次执行,这似乎取决于我更改间隔的次数。我尝试了两种方法:关闭并处理,但没有成功。
关于稍有不同主题的第二个问题。
我一直在看其他的.NET类和计时器类。第二个问题是如何将下面的VB示例代码转换为Python。“回调为TimerCallback”是否等同于myfunction(*my_args)?
Public Sub New ( _
callback As TimerCallback, _
state As Object, _
dueTime As Integer, _
period As Integer _
)
根据.NET文档: 回拨 类型:System.Threading.TimerCallback 表示要执行的方法的TimerCallback委托。 如果我定义的函数没有参数,例如:
def fun2(stateinfo):
# function code
它与:
self.Timer = Timer(fun2, self.autoEvent, self.dueTime,self.period)
如果我用更通用的函数调用my function(*my_args)替换fun2,函数调用将失败
也可以使用^{} 语法调用具有任意参数列表的函数:
用法:
也可以查看PEP8样式指南。Python首选的编码约定与许多其他通用语言不同。
问题1
每次使用加法赋值运算符(
+=
)时,都会向事件附加一个新的事件处理程序。例如,此代码:将打印
"Hello form my event handler"
短语两次。有关详细信息,您可以查看MSDN documentation,特别是Subscribe to and Unsubscribe from Events 。
因此,您可能应该将事件订阅移动到
__init__
方法,并且只在run_timer
方法中启动计时器:还可以添加新方法(或使用property)来更改间隔:
问题2
关于^{} 您是对的:它是一个表示要执行的方法的委托。
例如,这个^{} constructor :
应为具有类型为
Object
的单个参数的void
函数。当您使用
*
语法调用函数时,您所做的是完全不同的事情。如果我给你举个例子,可能会更容易:基本上,在第二种情况下,调用的是一个带有从元组解压的附加参数的函数。
因此,如果要将具有不同签名的函数传递给接受
TimerCallback
委托的构造函数,则必须创建一个新函数,就像@Lasse建议的那样。可以使用lambda关键字执行此操作:
或者通过声明一个新函数:
如果函数不接受任何参数,只需传递它而不调用它:
如果它接受参数,则需要将其转换为不接受参数的函数。您要做的是调用它,然后传递结果,在本例中是一个字符串。相反,请执行以下操作:
相关问题 更多 >
编程相关推荐