在Jython中,是否有向EDT提交方法的Pythonesque方法?
在Python中,人们习惯于这样做在Jython中,是否有向EDT提交方法的Pythonesque方法?,python,multithreading,jython,event-dispatch-thread,Python,Multithreading,Jython,Event Dispatch Thread,在Python中,人们习惯于这样做 def runTaskInNonEDT(): pass tRunTask = threading.Thread( target = runTaskInNonEDT ) tRunTask.start() 在Jython中,我发现如果我想向EDT提交一个方法,我必须去 def makeRunnableClass(): class RunnableClass( Runnable ): def run( rSelf ): pass r
def runTaskInNonEDT():
pass
tRunTask = threading.Thread( target = runTaskInNonEDT )
tRunTask.start()
在Jython中,我发现如果我想向EDT提交一个方法,我必须去
def makeRunnableClass():
class RunnableClass( Runnable ):
def run( rSelf ):
pass
return RunnableClass
SwingUtilities.invokeAndWait( makeRunnableClass()() )
很明显,你会遇到所有关于传递参数的问题,等等。
我只是想知道是否有一种更快捷、更具Python风格的方式向EDT提交方法
@lvc
谢谢。。。是的,事实上我明白了。。。其实这个成语
def makeSthgClass():
class SthgClass():
pass
return SthgClass
我习惯性地使用它来停止用一次性子类实例的类名混乱名称空间
事实上,我有sthg来减轻这项任务
def runToMessageTree( self, method, *args, **kvargs ):
if SwingUtilities.isEventDispatchThread():
method( *args, **kvargs )
else:
def makeRunnableClass():
class RunnableClass( Runnable ):
def run( self ):
method( *args, **kvargs )
return RunnableClass
SwingUtilities.invokeAndWait( makeRunnableClass()() )
所以你可以走了
def doSthg():
pass
self.runToMessageTree( doSthg )
。。。但这并没有什么令人满意的
后来:
class EDTWorkerThread( WorkerThread ):
def __init__( ewt_self, name ):
super( EDTWorkerThread, ewt_self ).__init__( name )
class EDTWorker( SwingWorker ):
def doInBackground(self ):
check_event_thread( False )
while True:
method_call_elements = ewt_self.input_queue.get()
if method_call_elements is None: # "poison pill"
break
self.super__publish( [ method_call_elements ])
ewt_self.input_queue.task_done()
return
def process( self, chunks ):
check_event_thread( True )
for chunk in chunks:
assert type( chunk ) is list
assert chunk # i.e. must have at least one element!
# check that first item is callable
assert hasattr( chunk[ 0 ], "__call__" )
method_call_elements = chunk
method_args = method_call_elements[ 1 : ]
method_call_elements[ 0 ]( *method_args )
ewt_self.input_queue.task_done()
ewt_self.swing_worker = EDTWorker()
def run( self ):
self.swing_worker.execute()
ẀorkerThread是一个非常简单、经典的python习语:
class WorkerThread( threading.Thread ):
def __init__( self, *args, **kvargs ):
threading.Thread.__init__( self, *args, **kvargs )
self.input_queue = Queue()
def send( self, item ):
assert type( item ) is list
assert item # i.e. must have at least one element!
# check that first item is callable
assert hasattr( item[ 0 ], "__call__" )
self.input_queue.put( item )
def close( self ):
self.input_queue.put( None )
self.input_queue.join()
def run( self ):
while True:
method_call_elements = self.input_queue.get()
if method_call_elements is None: # "poison pill"
break
method_args = method_call_elements[ 1 : ]
method_call_elements[ 0 ]( *method_args )
self.input_queue.task_done()
self.input_queue.task_done()
return
所以您提交了一个方法,后跟可选参数。。。然后,这个方法最终在EDT中运行,使用有问题的参数。不必创建任何可运行项
当然,另一种可能是从SwingWorker中派生子类。。。这样您就不会有这种稍微麻烦的“双队列”安排(即WorkerThread队列和EDT自己的队列,它将传递到process())。。。但是,在doInBackground中必须有一个相当不雅观的循环(使用sleep())
会对人们的观点感兴趣需要意识到的主要事情是
SwingUtilities.invokeAndWait
需要一个单一方法接口的实例,因为Java没有一流的函数。如果不为该功能使用除SwingUtilities
之外的其他工具,并且使用更具python风格的接口,则无法避免该位
如果您一心想使用那个特定的API,您仍然可以避免使用包装器函数。只要做:
class RunnableClass(Runnable):
def run(self):
pass
SwingUtilities.invokeAndWait(RunnableClass())
使用包装器函数的唯一原因是能够使用pass-in函数在run
中使用闭包进行调用;您仍然可以通过将函数传递到RunnableClass.\uuuu init\uuuu
并存储它来实现这一点:
class RunnableClass(Runnable):
def __init__(self, func):
self._func = func
def run(self):
self._func()
请注意,func
不应将self
作为第一个参数-因为它是实例上的属性,而不是类上的属性,所以不会将其视为方法
根据您的编辑-将func
传递到RunnableClass.\uuuu init\uuu
的目的是它不再需要是一个一次性子类-您不需要为要运行的每个func都使用Runnable
的一个子类,只需要一个RunnableClass
实例。该类本身是一个从Python习惯用法到Java习惯用法的通用适配器,因此您不需要围绕它使用函数来完成相同的工作
这意味着您的runToMessageTree
可以如下所示:
def runToMessageTree(self, method, *args, **kwargs):
if SwingUtilities.isEventDispatchThread():
method(*args, **kwargs)
else:
SwingUtilities.invokeAndWait(RunnableClass(method, *args, **kwargs))
当你编辑你的问题时,即使你在其中说@person,它实际上也不会通知那个人——通常的做法是更新它,然后在他们的答案上发表评论(或者在他们评论过的地方发表@person评论),说你已经更新了它。。。。话虽如此,我还是去做了同样的事情。请看我的最新答案。谢谢。是的,这是一个巧妙的技术,很好的pythonic。我想到的一件非常轻微的事情是,它仍然涉及到创建和提交Runnable。我想到的另一个选择是拥有一个(python)线程子类、一个封装的(python)队列和一个(Java)SwingWorker。。。工作非常好,我不知道性能的提高,如果有的话。已输入上述代码,欢迎发表任何意见