VB 델리게이트를 파이썬 이벤트 핸들러로 어떻게 변환합니까?

Nov 16 2020

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 앱의 일부입니다 .

Q :이 VB 델리게이트를 파이썬 이벤트 핸들러로 변환하는 올바른 방법은 무엇입니까?


나는 이미 다음과 같은 많은 변형을 시도했습니다.

...
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

여기에서 답변을 살펴 보았습니다.

  • 이 이벤트 처리기 등록을 C #에서 VB.net으로 변환하는 올바른 방법은 무엇입니까?
  • Python 클래스는 다른 언어와 같은 이벤트를 지원합니까?

답변

not2qubit Nov 24 2020 at 05:19

유사한 질문 에서이 답변 과 밀접하게 관련되어 있으므로 문제는 위임 코드를 지나치게 복잡하게 만드는 데있었습니다. 우리는 단순히 필요가 없습니다 OnTick의 클래스를 또한 실현 QuoteUpdatedHandler()이 필요 사 개 인수 우리가 대체하므로, printTick(...)그와 함께.

(물론 좀 더 복잡하거나 우아 하게 만들고 싶다면 클래스에서 만들고 싶을 것입니다.)

그런 다음 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)