WxPython PyPubSub,使用咖喱函数不起作用
WxPython PyPubSub, using curried function not working
我正在使用 WxPython
的 PyPubSub
模块来发送消息,我想要一个订阅主题的函数,该函数有一些柯里化参数。不幸的是,它似乎并没有像我期望的那样使用 curried 函数。
from functools import partial
import time
import wx
from pubsub import pub
def MakeStatusBar(top_frame):
statusbar = top_frame.CreateStatusBar()
statusbar.SetFieldsCount(2)
statusbar.SetStatusWidths([400, 400])
# pub.subscribe(listener=got_msg, topicName='game.new') # Works, when alone
status_func = partial(got_status_msg, statusbar)
print(f"status_func[callable={callable(status_func)}] = {status_func}")
status_func(some_data='Directly calling the curried-function') # Calling the function directly - works
pub.subscribe(listener=status_func, topicName='game.new') # Breaks
return statusbar
def got_msg(some_data):
print(f"\n*** got_msg: data = {some_data}\n")
def got_status_msg(status_bar, some_data):
print(f"\n*** got_status_msg, args = {some_data}\n")
status_bar.SetStatusText(some_data, 0)
class topFrame(wx.Frame):
def __init__(self, parent):
super().__init__(parent, wx.ID_ANY, title='testing', size=(500, 500))
self.status_bar = (MakeStatusBar(self))
class myApp(wx.App):
def __init__(self):
wx.App.__init__(self, redirect=True, filename='errlog.txt') # To log error to a file
# super().__init__(self) # Doesn't take redirect? Weird.
self.topFrame = topFrame(None)
self.SetTopWindow(self.topFrame)
self.topFrame.Show()
print(f"in 2 seconds, will send a message to the Statusbar")
time.sleep(2)
print(f"sending...\n")
try:
pub.sendMessage(topicName='game.new', some_data='publishing a new-game message')
except Exception as ex:
print(f"WTF? got {str(ex)}\n")
print(f"message has been sent.\n")
if __name__ == '__main__':
my_app = myApp()
my_app.MainLoop()
我得到的错误是:
Traceback (most recent call last):
File "/Code/wxpy/hex_test/src/wx/menu_bar.py", line 11, in new_game_msg
pub.sendMessage(topicName='game.new', some_data='this is a test message')
raise SenderUnknownMsgDataError(self.topicNameTuple,
pubsub.core.topicargspec.SenderUnknownMsgDataError:
Some optional args unknown in call to sendMessage('('game', 'new')', some_data): some_data
那么我如何才能将监听器函数传递给至少包含一个参数的主题?显然还有其他方法可以做到这一点(一个全局变量),但我觉得这应该可以通过部分函数来实现。
嗯,看了看,多看了文档,是的,有解决办法。它 已经 融入 PyPubSub
,其中侦听器本身已经允许柯里化参数。直接传入我想要的StatusBar参数就可以了
# status_func = partial(got_status_msg, statusbar)
# print(f"status_func[callable={callable(status_func)}] = {status_func}")
# status_func(some_data='Directly calling the curried-function') # Calling the function directly - works
pub.subscribe(listener=got_status_msg, topicName='game.new', status_bar=statusbar) # Now works
显然 PyPubSub
的开发者预料到了这种用途。干得好。 :)
我正在使用 WxPython
的 PyPubSub
模块来发送消息,我想要一个订阅主题的函数,该函数有一些柯里化参数。不幸的是,它似乎并没有像我期望的那样使用 curried 函数。
from functools import partial
import time
import wx
from pubsub import pub
def MakeStatusBar(top_frame):
statusbar = top_frame.CreateStatusBar()
statusbar.SetFieldsCount(2)
statusbar.SetStatusWidths([400, 400])
# pub.subscribe(listener=got_msg, topicName='game.new') # Works, when alone
status_func = partial(got_status_msg, statusbar)
print(f"status_func[callable={callable(status_func)}] = {status_func}")
status_func(some_data='Directly calling the curried-function') # Calling the function directly - works
pub.subscribe(listener=status_func, topicName='game.new') # Breaks
return statusbar
def got_msg(some_data):
print(f"\n*** got_msg: data = {some_data}\n")
def got_status_msg(status_bar, some_data):
print(f"\n*** got_status_msg, args = {some_data}\n")
status_bar.SetStatusText(some_data, 0)
class topFrame(wx.Frame):
def __init__(self, parent):
super().__init__(parent, wx.ID_ANY, title='testing', size=(500, 500))
self.status_bar = (MakeStatusBar(self))
class myApp(wx.App):
def __init__(self):
wx.App.__init__(self, redirect=True, filename='errlog.txt') # To log error to a file
# super().__init__(self) # Doesn't take redirect? Weird.
self.topFrame = topFrame(None)
self.SetTopWindow(self.topFrame)
self.topFrame.Show()
print(f"in 2 seconds, will send a message to the Statusbar")
time.sleep(2)
print(f"sending...\n")
try:
pub.sendMessage(topicName='game.new', some_data='publishing a new-game message')
except Exception as ex:
print(f"WTF? got {str(ex)}\n")
print(f"message has been sent.\n")
if __name__ == '__main__':
my_app = myApp()
my_app.MainLoop()
我得到的错误是:
Traceback (most recent call last):
File "/Code/wxpy/hex_test/src/wx/menu_bar.py", line 11, in new_game_msg
pub.sendMessage(topicName='game.new', some_data='this is a test message')
raise SenderUnknownMsgDataError(self.topicNameTuple,
pubsub.core.topicargspec.SenderUnknownMsgDataError:
Some optional args unknown in call to sendMessage('('game', 'new')', some_data): some_data
那么我如何才能将监听器函数传递给至少包含一个参数的主题?显然还有其他方法可以做到这一点(一个全局变量),但我觉得这应该可以通过部分函数来实现。
嗯,看了看,多看了文档,是的,有解决办法。它 已经 融入 PyPubSub
,其中侦听器本身已经允许柯里化参数。直接传入我想要的StatusBar参数就可以了
# status_func = partial(got_status_msg, statusbar)
# print(f"status_func[callable={callable(status_func)}] = {status_func}")
# status_func(some_data='Directly calling the curried-function') # Calling the function directly - works
pub.subscribe(listener=got_status_msg, topicName='game.new', status_bar=statusbar) # Now works
显然 PyPubSub
的开发者预料到了这种用途。干得好。 :)