运行next()时无法捕捉StopIteration如何解决?

环境:Windows10下的python3.8.1

运行如下代码:

while True:
  for n in playerlis:
    try:
      players[str(n)].append(next(self.gencards))
    except StopIteration:
      print('finish')
      break

期望无输出,实际输出如下:

Traceback (most recent call last):
  File "F:\card.py", line 88, in __init__
    self.players[str(n)].append(next(self.gencards))
StopIteration

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<pyshell#0>", line 1, in <module>
    a = onplayobj([1,2,3])
  File "F:\card.py", line 90, in __init__
    print('finish')
KeyboardInterrupt

 

for 循环底层自动帮你捕捉 StopIteration 异常并处理了,

  • For 循环被称为迭代器循环,in后跟的必须是可迭代对象

  • For 循环会执行 in 后面可迭代对象的 __iter__ 方法, 拿到迭代器对象

  • 然后调用迭代器对象的 __next__ 方法,拿到一个返回值赋值给 n,执行一次循环体

  • 周而复始, 直到取值完毕, For 循环会检测异常自动结束循环

代码能给全点么

import random,time
class card:
  def __init__(self,key=None,num=None,isjoker=False,isjokerbig=True):
    if not isjoker:
      self.key = key
      self.num = num
      self.name = str(key)+str(num)
    else:
      self.key = 'joker'
      if isjokerbig:
        self.num = 'big'
        self.name = 'big joker'
      else:
        self.num = 'small'
        self.name = 'small joker'
  def __str__(self,name=True):
      if name:
        return self.name
      else:
        return (self.key,self.num)
class allcards:
  def __init__(self):
    self.k = 'black red flower block'
    self.n = '2 3 4 5 6 7 8 9 10 J Q K A'
    self.k,self.n = self.k.split(),self.n.split()
    self.acards = [card(okey,onum) for okey in self.k for onum in self.n ]
    self.acards.extend([card(isjoker=True,isjokerbig=False),card(isjoker=True)])
  def __call__(self,one=False):
    if one:
      if self.acards:
        self.theone = random.choice(self.acards)
        self.acards.remove(self.theone)
        return self.theone
      else:
        raise TypeError('no more card')
    else:
      return list(self.acards)
  def didin(self,card):
    return True if card in self.cards else False
class allcardshm:
  def __init__(self,cmany):
    if 0 < cmany:
      self.cards = allcards()()
      if not cmany == 0:
        for _ in range(1,cmany):
          self.cards.extend(allcards()())
    else:
      raise TypeError('cannot make cards(cmany must bigger then 0)')
  def __call__(self,one=False):
    if one:
      if self.cards:
        self.theone = random.choice(self.cards)
        self.cards.remove(self.theone)
        return self.theone
      else:
        raise TypeError('no more card')
    else:
      return list(self.cards)
  def __str__(self):
    return self.acards
  def didin(self,card):
    return True if card in self.cards else False
def easyget(cardsobj,more=0):
  cardsobj = list(cardsobj())
  random.shuffle(cardsobj)
  if more == 0:
    while cardsobj:
      yield cardsobj.pop()
  else:
    mobj = []
    while len(mobj) != more:
      mobj.append(cardsobj.pop())
    yield modj
    while cardsobj:
      yield cardsobj.pop()
class onplayobj:
  def __init__(self,playerlis,cards=allcards()):
    if not type(cards) == type([]):
      self.cards = cards()
    else:
      self.cards = cards
    self.gencards = easyget(cards,(len(playerlis)-1)*2-1 if len(playerlis)<2 else 0)
    self.players = {str(name):[] for name in playerlis}
    self.dzcards = next(self.gencards)
    while True:
      for n in playerlis:
        try:
          self.players[str(n)].append(next(self.gencards))
        except StopIteration:
          print('finish')
          break
finish
finish
...
finish
finish
<ctrl-z>
Traceback (most recent call last):
  File "F:\card.py", line 88, in __init__
    self.players[str(n)].append(next(self.gencards))
StopIteration
 
During handling of the above exception, another exception occurred:
 
Traceback (most recent call last):
  File "<pyshell#0>", line 1, in <module>
    a = onplayobj([1,2,3])
  File "F:\card.py", line 90, in __init__
    print('finish')
KeyboardInterrupt