0
我創建了類似list()的類,但是可以向它添加字符串,這些字符串將被單詞上的空格分割,並且這些單詞將被添加到類實例。與減法相同:減法從類實例中刪除單詞(如果有的話)。鼻子測試+類迭代器=奇怪的行爲
我在鼻子測試中遇到了奇怪的行爲:當我只是改變聲明的順序時,行爲發生了變化。
下面是測試:
from nose.tools import *
def test_isub_str(self):
u = params()
u += "1 2 3 4"
u -= "2 3"
ok_("1" in u, u)
ok_("2" not in u, u)
ok_("3" not in u, u)
ok_("4" in u, u)
該測試失敗,並輸出如下:
Traceback (most recent call last):
File "tests.py", line 71, in test_isub_str
ok_("4" in u, u)
assert expr, msg
AssertionError: 1 4
怪, 「U」 被轉儲爲 「1 4」,而是 「4」 並不在斷言測試期間在「u」中找到。當我改變主張的以下列最有趣的情況:
ok_("1" in u, u)
ok_("4" in u, u)
ok_("2" not in u, u)
ok_("3" not in u, u)
然後測試都通過確定,這是正確的,預期的行爲。它看起來像「不在」語句改變了後面的「in」語句的行爲。我很驚訝。
最後,這裏是我的課:
class params():
def __init__(self):
self.index = 0 # iterator index
self.values = [] # list of stored values
def __iadd__(self, addvalues):
if isinstance(addvalues, str):
addvalues = addvalues.split(" ")
# add all values to this instance if they are list() or params()
# and not exist in current instance
if isinstance(addvalues, params) or isinstance(addvalues, list):
for value in addvalues:
if isinstance(value, str) and value not in self.values:
self.values.append(value)
else:
raise TypeError
return self
else:
raise TypeError
def __isub__(self, subvalues):
if isinstance(subvalues, str):
subvalues = subvalues.split(" ")
# substract all values from this instance if they are list() or params()
# and existing in current instance
if isinstance(subvalues, params) or isinstance(subvalues, list):
for value in subvalues:
if isinstance(value, str) and value in self.values:
self.values.remove(value)
else:
raise TypeError
return self
else:
raise TypeError
def __iter__(self):
return self
def next(self):
if self.index >= len(self.values):
raise StopIteration
else:
self.index += 1
return self.values[self.index - 1]
def __str__(self):
return " ".join(self.values)
所以問題是:爲什麼這樣奇怪的行爲發生?我在迭代器功能中遺漏了一些東西?或者這個鼻子測試錯誤?
謝謝!這是一個原因!我根據幾個不同的例子編寫了迭代器方法,如[this](http://stackoverflow.com/questions/19151/build-a-basic-python-iterator),他們都只是簡單地返回'self'。在每個__iter __()調用上重新設置索引/迭代器是否好的做法? – stunpix 2012-08-05 17:29:32
我認爲在這種情況下,最好刪除'next'方法(你實際上在你的迭代器中沒有任何狀態),並且改變'__iter__'這樣的東西:'iter(self.values)'。 – 2012-08-05 17:32:06
再次感謝。我按你的建議做了,'__iter __()'現在很簡單。 – stunpix 2012-08-06 08:30:25