cjb*_*ust 5 .net python ironpython class
我创建了一个可以使用一组参数的函数的类.我希望每次事件处理程序发出信号时都运行传递的函数.
我附加下面的代码,当我传递一个fun2没有参数但没有参数的时候fun1.我可以对下面的代码提出的任何建议fun1和fun2?如果我省略return语句fun1,我会收到错误'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()
Run Code Online (Sandbox Code Playgroud)
我正在学习Python,如果我的问题是基本的,我会道歉.
要更改间隔,我使用添加到timerTest类的stopTimer方法停止计时器:
def stopTimer(self):
self.Timer.Stop()
Run Code Online (Sandbox Code Playgroud)
我接受新的用户输入来调用我根据Paolo Moretti的建议修改的runTimer方法:
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
Run Code Online (Sandbox Code Playgroud)
只要按下命令按钮,就会调用以下方法:
requestTimer.runTimer((self.intervalnumericUpDown.Value* 1000),True, function, *args)
Run Code Online (Sandbox Code Playgroud)
我不明白为什么停止计时器并发送请求会导致runTimer方法多次执行,这似乎取决于我更改间隔的次数.我尝试了几种方法:关闭和处理没有成功.
关于略有不同主题的第二个问题.
我一直在使用Timer类查看其他.NET类.第二个问题是如何将以下VB示例代码转换为Python."callback As TimerCallback"等同于myfunction(*my_args)吗?
Public Sub New ( _
callback As TimerCallback, _
state As Object, _
dueTime As Integer, _
period As Integer _
)
Run Code Online (Sandbox Code Playgroud)
每个.NET文档:callback类型:System.Threading.TimerCallback一个TimerCallback委托,表示要执行的方法.如果我定义一个没有参数的函数,我可以部分地获取定时器事件,例如:
def fun2(stateinfo):
# function code
Run Code Online (Sandbox Code Playgroud)
适用于:
self.Timer = Timer(fun2, self.autoEvent, self.dueTime,self.period)
Run Code Online (Sandbox Code Playgroud)
如果我用更通用的函数调用my2(*my_args)替换fun2,函数调用将失败
您还可以使用*语法来调用具有任意参数列表的函数:
class TimerTest:
def __init__(self, interval, autoreset, fun, *args):
# ...
self.my_function = fun
self.my_args = args
# ...
def run_timer(self):
# ...
def on_timed_event(s, e):
# ...
self.my_function(*self.my_args)
# ...
Run Code Online (Sandbox Code Playgroud)
用法:
>>> t1 = TimerTest(1000, True, fun1, 10, 20)
>>> t2 = TimerTest(1000, True, fun2)
Run Code Online (Sandbox Code Playgroud)
并查看PEP8样式指南.Python的首选编码约定与许多其他常用语言不同.
问题1
每次使用加法赋值运算符(+=)时,都会为事件附加一个新的事件处理程序.例如这段代码:
timer = Timer()
def on_timed_event(s, e):
print "Hello form my event handler"
timer.Elapsed += on_timed_event
timer.Elapsed += on_timed_event
timer.Start()
Run Code Online (Sandbox Code Playgroud)
将打印"Hello form my event handler"短语两次.
有关更多信息,您可以查看MSDN文档,特别是订阅和取消订阅事件.
因此,您可能应该将事件订阅移动到该__init__方法,并且只在您的run_timer方法中启动计时器:
def run_timer(self):
self.Timer.Start()
Run Code Online (Sandbox Code Playgroud)
您还可以添加新方法(或使用属性)来更改间隔:
def set_interval(self, interval):
self.Timer.Interval = interval
Run Code Online (Sandbox Code Playgroud)
问题2
你是对的TimerCallback:它是代表一个要执行的方法的委托.
例如,这个Timer构造函数:
public Timer(
TimerCallback callback
)
Run Code Online (Sandbox Code Playgroud)
期望void具有单个参数类型的函数Object.
public delegate void TimerCallback(
Object state
)
Run Code Online (Sandbox Code Playgroud)
当您使用*语法调用函数时,您正在执行完全不同的操作.如果我给你举个例子,可能会更容易:
def foo(a, b, *args):
print a
print b
print args
>>> foo(1, 2, 3, 4, 5)
1
2
(3, 4, 5)
>>> args = (1, 2, 3)
>>> foo(1, 2, *args)
1
2
(1, 2, 3)
Run Code Online (Sandbox Code Playgroud)
基本上在第二种情况下,您正在调用一个函数,其中包含从元组中解压缩的其他参数.
因此,如果要将具有不同签名的函数传递给接受TimerCallback委托的构造函数,则必须创建一个新函数,如@Lasse所建议的那样.
def my_func(state, a, b):
pass
Run Code Online (Sandbox Code Playgroud)
您可以使用lambda关键字执行此操作:
t1 = Timer(lambda state: my_func(state, 1, 2))
Run Code Online (Sandbox Code Playgroud)
或者通过声明一个新功能:
def time_proc(state):
my_func(state, 1, 2)
t2 = Timer(time_proc)
Run Code Online (Sandbox Code Playgroud)
如果函数没有参数,只需传递它而不调用它:
b = timerTest(3000, True, fun2)
Run Code Online (Sandbox Code Playgroud)
如果需要参数,则需要将其转换为不带参数的函数.你正在做的是调用它,然后传递结果,在这种情况下是一个字符串.而是这样做:
a = timerTest(1000, True, lambda: fun1(10, 20))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7013 次 |
| 最近记录: |