StopIteration不会被main捕获

问题描述

我要发送的数字大于999999999时,我想引发stopiteration异常。

当我直接向print(check_id_valid(1234567980))函数参数或IDIterator类(迭代器class)发送参数,并从那里将数字传递给check_id_valid()函数时,捕获到异常放在main()上。 错误字符串将被打印:

Reached max number,1234567980 is over 9 digits

但是当我将数字发送到id_generator()函数时(感谢先前的帮助,该函数正常工作),

stopiteration不会引发main()异常

def check_id_valid(id_number):

     if len(str(id_number)) < 9:
         raise illigalException(id_number)        
     if int(id_number) > 999999999:
         raise stopiteration(id_number)
def id_generator(Id_number):
   while True:
       Id_number += 1
       if check_id_valid(Id_number):
           yield Id_number
def main():
 
    id_gen = id_generator(1234567800)
    try:
        for item in range(10):   
            print(next(id_gen))

    except stopiteration as e:
        print("Reached max number," + str(e)  + " is over 9 digits")
    except (illigalException) as e:
        print(e)

if __name__ == "__main__":
    main()

错误消息是-

raise stopiteration(id_number) stopiteration: 1234567801 The above exception was the direct cause of the following exception:

print(next(id_gen)) RuntimeError: generator raised stopiteration

我该如何解决

PS

我需要使用内置的stopiteration异常,而不是覆盖它。

解决方法

Python生成器返回时将自动引发StopIteration。因此,您不应该自己在生成器函数中引发StopIteration

StopIteration在迭代器中用于停止迭代,例如在for循环内。

def check_id_valid(id_number):

     if len(str(id_number)) < 9:
         raise illigalException(id_number)        
     if int(id_number) > 999999999:
         return False

     # you need to return True if is valid.
     return True


def id_generator(Id_number):
   while True:
       Id_number += 1
       if check_id_valid(Id_number):
           yield Id_number
       
       else:
           # this return here will raise the StopIteration error with message id_number for you.
           return id_number
          

更新

# assuming your check_id_valid is still the same.
def id_generator(Id_number):
    while True:
        Id_number += 1
        try:
            check_id_valid(Id_number)
        except StopIteration:
            # this return will raise StopIteration when you call next() on id_generator
            return Id_number
        except Exception as e:
            # raise the other illigalException 
            raise e
        
        yield Id_number