子类化 Future Class
Subclassing Future Class
我想子class Future class concurrent
Python 模块。
文档:
The Future class encapsulates the asynchronous execution of a callable. Future instances are created by Executor.submit().
Executor
的文档没有解释 Future
class 的来源。
...如何使 Executor.submit() 强制采用我的自定义 Future class?
为什么我需要它?
我喜欢 OOP,因为它创建了可读的代码。我希望结果如下所示:
for my_future in concurrent.futures.as_completed(...):
my_future.my_custom_method()
Future
具体 class 的使用被硬连接到 Executor.submit()
(无论是 processes or threads)。因此,我认为不可能完全按照您的要求去做。但是,您可以 return 传递给 Executor.submit()
的可调用结果的任何结果。因此,将您的自定义方法放在自定义 return class:
class my_result(object):
def my_custom_method(self):
pass
def x():
return my_result()
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
futures = [executor.submit(x), executor.submit(x)]
for my_future in concurrent.futures.as_completed(futures):
my_future.result().my_custom_method()
# ^^^^^^^^^
编辑 或者,如果您真的希望您的内部循环干净,请将最后两行更改为:
for my_result in (f.result() for f in concurrent.futures.as_completed(futures)):
# ^^^^^^^^^^^^^^^^^^^^
my_result.my_custom_method()
generator expression (f.result() ... (futures))
从 as_completed
中获取期货的迭代器,并为您提供这些期货结果的迭代器。然后您可以遍历这些结果。
查看代码,ProcessPoolExecutor.submit() and ThreadPollExecutor.submit(), Excutor.submit()
returns an instance of Future, which is defined in conccurent.futures._base.Future
。
所以,技巧来了。可以子类化替换原来的Future,然后在子类中添加自定义方法。
可行,但不推荐。为此,最好使用组合而不是继承。 Learn Python the Hard Way
中有一个很好的关于继承和组合的章节
回到问题,举个例子:
class Myclass(object):
def __init__(self, workers=3):
self.executor = concurrent.futures.ProcessPoolExcutor(workers)
def run(self, job):
'''Job to be run in a Executor'''
def submit(self, jobs):
self.futures = [executor.submit(self, foo, job) for job in jobs]
def done(self, result):
'''Dealing with the result'''
def harvest(self):
for my_future in concurrent.futures.as_completed(self.futures):
self.done(my_future.result())
然后你可以继承 MyClass
并实现不同的 done 方法。
我想子class Future class concurrent
Python 模块。
文档:
The Future class encapsulates the asynchronous execution of a callable. Future instances are created by Executor.submit().
Executor
的文档没有解释 Future
class 的来源。
...如何使 Executor.submit() 强制采用我的自定义 Future class?
为什么我需要它?
我喜欢 OOP,因为它创建了可读的代码。我希望结果如下所示:
for my_future in concurrent.futures.as_completed(...):
my_future.my_custom_method()
Future
具体 class 的使用被硬连接到 Executor.submit()
(无论是 processes or threads)。因此,我认为不可能完全按照您的要求去做。但是,您可以 return 传递给 Executor.submit()
的可调用结果的任何结果。因此,将您的自定义方法放在自定义 return class:
class my_result(object):
def my_custom_method(self):
pass
def x():
return my_result()
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
futures = [executor.submit(x), executor.submit(x)]
for my_future in concurrent.futures.as_completed(futures):
my_future.result().my_custom_method()
# ^^^^^^^^^
编辑 或者,如果您真的希望您的内部循环干净,请将最后两行更改为:
for my_result in (f.result() for f in concurrent.futures.as_completed(futures)):
# ^^^^^^^^^^^^^^^^^^^^
my_result.my_custom_method()
generator expression (f.result() ... (futures))
从 as_completed
中获取期货的迭代器,并为您提供这些期货结果的迭代器。然后您可以遍历这些结果。
查看代码,ProcessPoolExecutor.submit() and ThreadPollExecutor.submit(), Excutor.submit()
returns an instance of Future, which is defined in conccurent.futures._base.Future
。
所以,技巧来了。可以子类化替换原来的Future,然后在子类中添加自定义方法。
可行,但不推荐。为此,最好使用组合而不是继承。 Learn Python the Hard Way
中有一个很好的关于继承和组合的章节回到问题,举个例子:
class Myclass(object):
def __init__(self, workers=3):
self.executor = concurrent.futures.ProcessPoolExcutor(workers)
def run(self, job):
'''Job to be run in a Executor'''
def submit(self, jobs):
self.futures = [executor.submit(self, foo, job) for job in jobs]
def done(self, result):
'''Dealing with the result'''
def harvest(self):
for my_future in concurrent.futures.as_completed(self.futures):
self.done(my_future.result())
然后你可以继承 MyClass
并实现不同的 done 方法。