2015-07-12 62 views
3

按照该documentation,有队列的几种实现。我感兴趣的是JoinableQueue和PriorityQueue,因为我希望有一个带有优先级的可连接队列。可连接的PriorityQueue在python的ASYNCIO

看来我只能得到低版本的功能之一。即在3.5中,我可以用Queue(可连接)和PriorityQueue来区分,但是在Python下面的3.5中有JoinableQueue和PriorityQueue(请参见下面的示例)。

是否有可能将它们组合在一起去获得3.4可连接的PriorityQueue一般的方法是什么?

try: 
    # Python 3.4. 
    from asyncio import JoinableQueue as Queue # joinable 
    from asyncio import PriorityQueue   # I assume this one is not joinable 
except ImportError: 
    # Python 3.5. 
    from asyncio import Queue     # standard joinable 
    from asyncio import PriorityQueue   # I assume this is the one I want 

另一种方法是以某种方式影响队列?

回答

4

,因为这样JoinableQueuePriorityQueue实现,你可以都通过多重继承继承获得JoinablePriorityQueue,只要你列出JoinableQueue第一。

这部作品的原因是PriorityQueue很简单地实现:

class PriorityQueue(Queue): 
    """A subclass of Queue; retrieves entries in priority order (lowest first). 

    Entries are typically tuples of the form: (priority number, data). 
    """ 

    def _init(self, maxsize): 
     self._queue = [] 

    def _put(self, item, heappush=heapq.heappush): 
     heappush(self._queue, item) 

    def _get(self, heappop=heapq.heappop): 
     return heappop(self._queue) 

虽然JoinableQueue较为复杂,唯一的方法它和PriorityQueue实施是_put,也是至关重要的一点,JoinableQUeue电话super()._put(..)在自己put实施,这意味着它将与PriorityQueue正确合作。

下面是一个例子,证明它的工作原理:

from asyncio import PriorityQueue, JoinableQueue 
import asyncio 
import random 

class JoinablePriorityQueue(JoinableQueue, PriorityQueue): 
    pass 


@asyncio.coroutine 
def consume(q): 
    while True: 
     a = yield from q.get() 
     print("got a {}".format(a)) 
     if a[1] is None: 
      q.task_done() 
      return 
     asyncio.sleep(1) 
     q.task_done() 

@asyncio.coroutine 
def produce(q): 
    for i in range(10): 
     yield from q.put((random.randint(0,10), i)) 
    yield from q.put((100, None)) # Will be last 
    asyncio.async(consume(q)) 
    print("waiting...") 
    yield from q.join() 
    print("waited") 

loop = asyncio.get_event_loop() 
q = JoinablePriorityQueue() 
loop.run_until_complete(produce(q)) 

输出:

waiting... 
got a (1, 2) 
got a (2, 1) 
got a (4, 4) 
got a (5, 0) 
got a (6, 8) 
got a (6, 9) 
got a (8, 3) 
got a (9, 5) 
got a (9, 7) 
got a (10, 6) 
got a (100, None) 
waited 
+0

我希望的方式得到你的注意,知道你还参与了AIO :) – PascalVKooten

+0

@PascalvKooten我没有开发任何核心的'asyncio'代码,只是一个建立在它上面的第三方模块('aioprocessing')。这和我在这里回答了很多关于它的问题。 [Andrew Svetlov](http://stackoverflow.com/users/3454879/andrew-svetlov),他也在这里回答了很多关于asyncio的问题,我确实开发了一些核心代码。 – dano