如何将 VB 委托转换为 python 事件处理程序?
How do I convert a VB delegate into a python event handler?
我必须使用 python.net 将订阅 委托 (事件)的以下 VB 代码重写为 python .
Imports MtApi
Public Class Form1
Private apiClient As MtApiClient
Public Sub New()
InitializeComponent()
apiClient = New MtApiClient
AddHandler apiClient.QuoteUpdated, AddressOf QuoteUpdatedHandler
End Sub
Sub QuoteUpdatedHandler(sender As Object, symbol As String, bid As Double, ask As Double)
Dim quoteSrt As String
quoteSrt = symbol + ": Bid = " + bid.ToString() + "; Ask = " + ask.ToString()
ListBoxQuotesUpdate.Invoke(Sub()
ListBoxQuotesUpdate.Items.Add(quoteSrt)
End Sub)
Console.WriteLine(quoteSrt)
End Sub
' These can be ignored for this discussion
Private Sub btnConnect_Click(sender As System.Object, e As System.EventArgs) Handles btnConnect.Click
apiClient.BeginConnect(8222)
End Sub
Private Sub btnDisconnect_Click(sender As System.Object, e As System.EventArgs) Handles btnDisconnect.Click
apiClient.BeginDisconnect()
End Sub
End Class
此 VB 代码是 mtapi .NET 桥的 VB 应用程序的一部分。
问:将此 VB 委托转换为 python 事件处理程序的正确方法是什么?
我已经尝试了以下多种变体:
...
import MtApi as mt
...
# apiClient_QuoteUpdated(object sender, string symbol, double bid, double ask)
def printTick(symbol, ask, bid):
print('Tick: Symbol: {} Ask: {:.5f} Bid: {:.5f}'.format(symbol, ask, bid))
class OnTick:
def __init__(self):
self.listeners = []
def __iadd__(self, listener):
# Shortcut for using += to add a listener
self.listeners.append(listener)
return self
def notify(self, *args, **kwargs):
for listener in self.listeners:
listener(*args, **kwargs)
mtc = mt.MtApiClient()
res = mtc.BeginConnect('127.0.0.1', 8222);
# This Works!
newTick = OnTick()
newTick += printTick
newTick.notify(SYM, 1.12400, 1.12300)
# This does NOT work!
newTick.notify(mtc.QuoteUpdate())
# TypeError: 'EventBinding' object is not callable
一直在这里查看答案:
- Does Python classes support events like other languages?
与类似问题中的 密切相关,问题在于委托代码过于复杂。我们根本不需要 OnTick class 并且还意识到 QuoteUpdatedHandler()
需要 4 arguments,所以我们用那个替换 printTick(...)
。
(当然,如果您确实想让某些东西变得更复杂或 优雅,您确实希望在 class 中创建它.)
然后 VB 委托的等效 Python 代码变为:
...
def QuoteUpdatedHandler(source, sym, bid, ask) :
qstr = '{}: {:.5f} {:.5f}'.format(sym,bid,ask)
print(qstr)
...
mtc = mt.MtApiClient()
print('Connecting...')
res = mtc.BeginConnect('127.0.0.1', 8222);
# VB: AddHandler mtc.QuoteUpdated, AddressOf QuoteUpdatedHandler
# Because we want the "AddressOf" of the function, we don't use the invoking "()"
mtc.QuoteUpdated += QuoteUpdatedHandler
print('ok')
# Now run in a loop and wait for the events:
while 1:
pass
try:
time.sleep(0.1)
except KeyboardInterrupt:
print('\n Break!')
break
if (mtc.IsConnected()) :
mtc.PlaySound("tick")
mtc.BeginDisconnect()
print('\n Done!')
sys.exit(2)
我必须使用 python.net 将订阅 委托 (事件)的以下 VB 代码重写为 python .
Imports MtApi
Public Class Form1
Private apiClient As MtApiClient
Public Sub New()
InitializeComponent()
apiClient = New MtApiClient
AddHandler apiClient.QuoteUpdated, AddressOf QuoteUpdatedHandler
End Sub
Sub QuoteUpdatedHandler(sender As Object, symbol As String, bid As Double, ask As Double)
Dim quoteSrt As String
quoteSrt = symbol + ": Bid = " + bid.ToString() + "; Ask = " + ask.ToString()
ListBoxQuotesUpdate.Invoke(Sub()
ListBoxQuotesUpdate.Items.Add(quoteSrt)
End Sub)
Console.WriteLine(quoteSrt)
End Sub
' These can be ignored for this discussion
Private Sub btnConnect_Click(sender As System.Object, e As System.EventArgs) Handles btnConnect.Click
apiClient.BeginConnect(8222)
End Sub
Private Sub btnDisconnect_Click(sender As System.Object, e As System.EventArgs) Handles btnDisconnect.Click
apiClient.BeginDisconnect()
End Sub
End Class
此 VB 代码是 mtapi .NET 桥的 VB 应用程序的一部分。
问:将此 VB 委托转换为 python 事件处理程序的正确方法是什么?
我已经尝试了以下多种变体:
...
import MtApi as mt
...
# apiClient_QuoteUpdated(object sender, string symbol, double bid, double ask)
def printTick(symbol, ask, bid):
print('Tick: Symbol: {} Ask: {:.5f} Bid: {:.5f}'.format(symbol, ask, bid))
class OnTick:
def __init__(self):
self.listeners = []
def __iadd__(self, listener):
# Shortcut for using += to add a listener
self.listeners.append(listener)
return self
def notify(self, *args, **kwargs):
for listener in self.listeners:
listener(*args, **kwargs)
mtc = mt.MtApiClient()
res = mtc.BeginConnect('127.0.0.1', 8222);
# This Works!
newTick = OnTick()
newTick += printTick
newTick.notify(SYM, 1.12400, 1.12300)
# This does NOT work!
newTick.notify(mtc.QuoteUpdate())
# TypeError: 'EventBinding' object is not callable
一直在这里查看答案:
- Does Python classes support events like other languages?
与类似问题中的 QuoteUpdatedHandler()
需要 4 arguments,所以我们用那个替换 printTick(...)
。
(当然,如果您确实想让某些东西变得更复杂或 优雅,您确实希望在 class 中创建它.)
然后 VB 委托的等效 Python 代码变为:
...
def QuoteUpdatedHandler(source, sym, bid, ask) :
qstr = '{}: {:.5f} {:.5f}'.format(sym,bid,ask)
print(qstr)
...
mtc = mt.MtApiClient()
print('Connecting...')
res = mtc.BeginConnect('127.0.0.1', 8222);
# VB: AddHandler mtc.QuoteUpdated, AddressOf QuoteUpdatedHandler
# Because we want the "AddressOf" of the function, we don't use the invoking "()"
mtc.QuoteUpdated += QuoteUpdatedHandler
print('ok')
# Now run in a loop and wait for the events:
while 1:
pass
try:
time.sleep(0.1)
except KeyboardInterrupt:
print('\n Break!')
break
if (mtc.IsConnected()) :
mtc.PlaySound("tick")
mtc.BeginDisconnect()
print('\n Done!')
sys.exit(2)