0

list()のように動作するクラスを作成していますが、文字列を追加できます。これらの文字列は単語のスペースで分割され、これらの単語がクラスインスタンスに追加されます。substractionと同じ:substractionは、クラスインスタンス(存在する場合)から単語を削除します。

ノーズテストで奇妙な動作に直面しました。アサーションの順序を変更するだけで動作が変わります。

これがテストです:

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」としてダンプされますが、アサーションテスト中に「u」に「4」が見つかりませんでした。そして、最も興味深いのは、アサーションの順序を次のように変更したときに発生します。

ok_("1" in u, u)
ok_("4" in u, u)
ok_("2" not in u, u)
ok_("3" not in u, u)

その後、テストはOKに合格し、これは正しい、期待される動作です。「notin」ステートメントは、後続の「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)

だから問題は:なぜそのような奇妙な行動が起こるのですか?イテレータ機能で何かを逃しましたか?または、このノーズテストのバグですか?

4

1 に答える 1

0

いいえ、それはノーズテストのバグではありません。

ok_("1" in u, u)

次の場合、u.indexは1です。

ok_("2" not in u, u)
ok_("3" not in u, u)

u.indexは2です。

ok_("4" in u, u)

u.indexはまだ2であり、2が> = len(self.values)であるため、「next」メソッドはStopIterationを発生させます。

2番目のケースでは、次の場合でもu.indexは1のままです。

ok_("4" in u, u)
于 2012-08-05T16:32:39.510 に答える