Python專案實戰之迭代器實現字串的逆序輸出

2020-07-16 10:05:04
《Python疊代器》一節已經對如何建立疊代器做了詳細的介紹,本節將利用疊代器完成對字串的逆序操作。專案要求是這樣的,定義一個類,要求在實現疊代器功能的基礎上,能夠對使用者輸入的字串做逆序輸出操作。

實現思路是這樣的,自定義一個類並過載其 __init__() 初始化方法,實現為自身私有成員賦值。同時過載 __iter__() 和 __next__() 方法,使其具有疊代器功能。在此基礎上,如果想實現對使用者輸入的字串進行逆序輸出,就需要在 __next__() 方法中實現從後往前返回字元。

實現程式碼如下:
class Reverse:
    def __init__(self, string):
        self.__string = string
        self.__index = len(string)
    def __iter__(self):
        return self
    def __next__(self):
        self.__index -= 1
        return self.__string[self.__index]
revstr = Reverse('Python')
for c in revstr:
    print(c,end=" ")
執行結果為:

n o h t y P n o h t y P Traceback (most recent call last):
  File "C:UsersmengmaDesktopdemo.py", line 11, in <module>
    for c in revstr:
  File "C:UsersmengmaDesktopdemo.py", line 9, in __next__
    return self.__string[self.__index]
IndexError: string index out of range

可以看到,上面程式在逆序輸出兩遍"python"的同時,Python直譯器報出 IndexError 錯誤,這是什麼原因呢?

很簡單,因為程式沒有設定遍歷的終止條件,換句話說,沒有對 __index 私有變數的值對限制,這裡 __index 的取值範圍應為(-len(self.__index), len(self.__index)),這也是導致上面程式執行結果的根本原因。

編寫疊代器最容易忽視的一個環節,就是在自定義類中加入對迴圈結束的判斷,並丟擲 StopIteration 異常,只有這麼做了,for 迴圈才會接收到 StopIteration 異常,並當做終止信號來結束回圈。

所以,我們需要對上面程式做適當的調整,如下所示:
class Reverse:
    def __init__(self, string):
        self.__string = string
        self.__index = len(string)
    def __iter__(self):
        return self
    def __next__(self):
        if self.__index == 0:
            raise(StopIteration)
        self.__index -= 1
        return self.__string[self.__index]
revstr = Reverse('Python')
for c in revstr:
    print(c,end=" ")
執行結果為:

n o h t y P