Python协程时间切片

时间:2019-04-12 10:47:39

标签: python coroutine

我正在从这里开始学习如何使用协程,而视频中的文章将以下内容作为示例

  

国际象棋大师朱迪特·波尔加尔(JuditPolgár)举办国际象棋展览,她在其中下棋   多个业余玩家。她有两种方式进行   展览:同步和异步。

     

假设:

24 opponents
Judit makes each chess move in 5 seconds
Opponents each take 55 seconds to make a move
Games average 30 pair-moves (60 moves total)
     

同步版本:Judit一次只能玩一场游戏,而从不玩两次   同时,直到游戏完成。每局需要(55 + 5)* 30   == 1800秒或30分钟。整个展览需要24 * 30 == 720分钟或12个小时。

     

异步版本:Judit从一张桌子移到另一张桌子,一举一动   在每个桌子上。她离开桌子,让对手做出自己的决定   等待时间内的下一步行动。 Judit在所有24场比赛中一招   24 * 5 == 120秒或2分钟。现在整个展览都被剪掉了   降至120 * 30 == 3600秒,或仅1小时。

写的内容来自https://youtu.be/iG6fr81xHKA?t=4m29s

如果我要为国际象棋展览编写代码,我的程序将包含24个协程,并且必须在5秒内完成并移至下一个协程。

因此,我的问题是,在python中编写了24个函数,几乎同一件事都被认为是不好的编码实践,如果可以的话,该怎么办?

编辑

从此示例https://github.com/prompt-toolkit/python-prompt-toolkit/blob/master/examples/other/coroutines-and-futures.py

我看到我们可以执行24个功能。

1 个答案:

答案 0 :(得分:0)

这是实现它的一种方式:

a

输出:

import asyncio


class Player:
    def __init__(self, name: str, seconds_per_turn: float):
        self.name = name
        self.seconds_per_turn = seconds_per_turn
        self.busy = asyncio.Condition()

    async def move(self, game):
        await self.busy.acquire()
        print(f'game {game.game_number} player {self.name} begins {self.seconds_per_turn} second move')
        await asyncio.sleep(self.seconds_per_turn)
        print(f'game {game.game_number} player {self.name} ends {self.seconds_per_turn} second move')
        self.busy.release()


class Game:
    def __init__(self, game_number: int, player1: Player, player2: Player, number_of_turns: int):
        self.game_number = game_number
        self.player1 = player1
        self.player2 = player2
        self.number_of_turns = number_of_turns

    async def start(self):
        print(f'game {self.game_number} started')
        for turn in range(1, self.number_of_turns + 1):
            print(f'game {self.game_number} turn #{turn}')
            await self.player1.move(self)
            await self.player2.move(self)
        print(f'game {self.game_number} ended')


if __name__ == '__main__':
    synchronous = False
    loop = asyncio.get_event_loop()
    judit = Player('judit', 5)
    for i in range(1, 25):
        opponent = Player(f'opponent {i}', 55)
        game = Game(i, judit, opponent, 30)
        if synchronous:
            loop.run_until_complete(game.start())
        else:
            asyncio.ensure_future(game.start())
    loop.run_forever()

通过将game 1 started game 1 turn #1 game 1 player judit begins 5 second move game 2 started game 2 turn #1 game 3 started game 3 turn #1 game 4 started game 4 turn #1 game 5 started game 5 turn #1 game 6 started game 6 turn #1 game 7 started game 7 turn #1 game 8 started game 8 turn #1 game 9 started game 9 turn #1 game 10 started game 10 turn #1 game 11 started game 11 turn #1 game 12 started game 12 turn #1 game 13 started game 13 turn #1 game 14 started game 14 turn #1 game 15 started game 15 turn #1 game 16 started game 16 turn #1 game 17 started game 17 turn #1 game 18 started game 18 turn #1 game 19 started game 19 turn #1 game 20 started game 20 turn #1 game 21 started game 21 turn #1 game 22 started game 22 turn #1 game 23 started game 23 turn #1 game 24 started game 24 turn #1 game 1 player judit ends 5 second move game 1 player opponent 1 begins 55 second move game 2 player judit begins 5 second move game 2 player judit ends 5 second move game 2 player opponent 2 begins 55 second move game 3 player judit begins 5 second move game 3 player judit ends 5 second move game 3 player opponent 3 begins 55 second move game 4 player judit begins 5 second move game 4 player judit ends 5 second move game 4 player opponent 4 begins 55 second move game 5 player judit begins 5 second move game 5 player judit ends 5 second move game 5 player opponent 5 begins 55 second move game 6 player judit begins 5 second move game 6 player judit ends 5 second move game 6 player opponent 6 begins 55 second move game 7 player judit begins 5 second move game 7 player judit ends 5 second move game 7 player opponent 7 begins 55 second move game 8 player judit begins 5 second move game 8 player judit ends 5 second move game 8 player opponent 8 begins 55 second move game 9 player judit begins 5 second move game 9 player judit ends 5 second move game 9 player opponent 9 begins 55 second move game 10 player judit begins 5 second move game 10 player judit ends 5 second move game 10 player opponent 10 begins 55 second move game 11 player judit begins 5 second move game 11 player judit ends 5 second move game 11 player opponent 11 begins 55 second move game 12 player judit begins 5 second move game 1 player opponent 1 ends 55 second move game 1 turn #2 game 12 player judit ends 5 second move game 12 player opponent 12 begins 55 second move game 13 player judit begins 5 second move game 2 player opponent 2 ends 55 second move game 2 turn #2 game 13 player judit ends 5 second move game 13 player opponent 13 begins 55 second move game 14 player judit begins 5 second move game 3 player opponent 3 ends 55 second move game 3 turn #2 game 14 player judit ends 5 second move game 14 player opponent 14 begins 55 second move game 15 player judit begins 5 second move game 4 player opponent 4 ends 55 second move game 4 turn #2 game 15 player judit ends 5 second move game 15 player opponent 15 begins 55 second move game 16 player judit begins 5 second move game 5 player opponent 5 ends 55 second move game 5 turn #2 game 16 player judit ends 5 second move game 16 player opponent 16 begins 55 second move game 17 player judit begins 5 second move game 6 player opponent 6 ends 55 second move game 6 turn #2 game 17 player judit ends 5 second move game 17 player opponent 17 begins 55 second move game 18 player judit begins 5 second move game 7 player opponent 7 ends 55 second move game 7 turn #2 game 18 player judit ends 5 second move game 18 player opponent 18 begins 55 second move game 19 player judit begins 5 second move game 8 player opponent 8 ends 55 second move game 8 turn #2 game 19 player judit ends 5 second move game 19 player opponent 19 begins 55 second move game 20 player judit begins 5 second move game 9 player opponent 9 ends 55 second move game 9 turn #2 game 20 player judit ends 5 second move game 20 player opponent 20 begins 55 second move game 21 player judit begins 5 second move game 10 player opponent 10 ends 55 second move game 10 turn #2 game 21 player judit ends 5 second move game 21 player opponent 21 begins 55 second move game 22 player judit begins 5 second move game 11 player opponent 11 ends 55 second move game 11 turn #2 game 22 player judit ends 5 second move game 22 player opponent 22 begins 55 second move game 23 player judit begins 5 second move game 12 player opponent 12 ends 55 second move game 12 turn #2 game 23 player judit ends 5 second move game 23 player opponent 23 begins 55 second move game 24 player judit begins 5 second move game 13 player opponent 13 ends 55 second move game 13 turn #2 game 24 player judit ends 5 second move game 24 player opponent 24 begins 55 second move game 1 player judit begins 5 second move game 14 player opponent 14 ends 55 second move game 14 turn #2 game 1 player judit ends 5 second move game 1 player opponent 1 begins 55 second move game 2 player judit begins 5 second move game 15 player opponent 15 ends 55 second move game 15 turn #2 game 2 player judit ends 5 second move game 2 player opponent 2 begins 55 second move game 3 player judit begins 5 second move game 16 player opponent 16 ends 55 second move game 16 turn #2 game 3 player judit ends 5 second move game 3 player opponent 3 begins 55 second move [...] 设置为synchrounous,必须在第二场比赛开始之前完成第一场比赛。

带有True的输出:

synchrounous = True