Python 3 doctest:doctest 和真实评估之间的不同行为

Python 3 doctest : different behavior between doctest and real evaluation

当我使用 doctest 模块调用我的函数之一时,结果与函数的经典调用不同。

如何才能通过测试? 提前谢谢你:-)

这是我正常调用 print(bfs(arbreBFS)) 时得到的结果:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

这是我从 doctest 调用它时得到的结果:

Failed example:
    print(bfs(arbreBFS))
Expected:
    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
Got:
    [1, 4, 3, 2, 8, 7, 6, 5, 12, 11, 10, 9]

这是完整的代码。很抱歉不能少给一点,但我不明白是哪一部分给我带来了这个问题。

def func_false(*args):
    return False

def value_getter(noeud):
    return noeud.value

class Noeud():
    def __init__(self, value=None, enfants=[]):
        self.value = value
        self.enfants = enfants

    def ajouter_enfant(self, enfant):
        self.enfants.append(enfant)


class AbstractCollectionIterator():
    def __init__(self, collection):
        self.collection = collection    

    def __next__(self):
        if len(self.collection._contenu) == 0:
            raise StopIteration
        return self.collection._contenu.pop()


class AbstractCollection():
    _contenu = []

    def length(self):
        return len(self._contenu)

    def __str__(self):
        return self._contenu.__str__()

    def __iter__(self):
        return AbstractCollectionIterator(self)

class FIFO(AbstractCollection):

    def push(self, obj):
        self._contenu.insert(0, obj)

    def push_mul(self, objs):
        if len(objs) == 0:
            return
        objs.reverse()
        self._contenu = objs + self._contenu 

    def pop(self):
        return self._contenu.pop() 


def _parcours_collection_func(arbre, collection, func, func_goal=func_false):
    collection.push(arbre)
    values = []
    while collection.length() > 0:
        noeud = collection.pop()
        if func_goal(noeud):
            continue
        values.append(func(noeud))
        collection.push_mul(noeud.enfants)
    return values


def genere_enfants(node_info):
    """
        Generate a node and its children

        node_info format : (<node_value>, [<list_of_children>])
        <node_value> : int
        <list_of_children> : <node_info_1>, <node_info_2> ...
    """
    liste_enfants = []

    for donnees_noeud in node_info:
        if isinstance(donnees_noeud, list) or isinstance(donnees_noeud, tuple):
            enfant = genere_enfants(donnees_noeud[1])
            noeud = Noeud(donnees_noeud[0], enfant)
        else:
            noeud = Noeud(donnees_noeud, [])
        liste_enfants.append(noeud)
    return liste_enfants


def genere_arbre(valeur, node_info):
    return Noeud(valeur, genere_enfants(node_info))


arbreBFS = genere_arbre(1, [ (2, [ (5, [(9), (10)]), (6)]),
                              (3),
                              (4, [ (7, [(11), (12)]), (8)])
                           ])

def bfs(arbre, func=value_getter, func_goal=func_false):
    """

        :Exemple:

        >>> print(bfs(arbreBFS))
        [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
    """
    return _parcours_collection_func(arbre, FIFO(), func, func_goal)


print(bfs(arbreBFS))
import doctest
doctest.testmod()

这是 arbreBFS 的样子:

Schéma de l'arbre arbreBFS

不是different behavior between doctest and real evaluation。这是您的代码的不一致行为。让我们 运行 代码不止一次:

print(bfs(arbreBFS))
print(bfs(arbreBFS))
print(bfs(arbreBFS))
print(bfs(arbreBFS))

输出如下:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
[1, 4, 3, 2, 8, 7, 6, 5, 12, 11, 10, 9]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
[1, 4, 3, 2, 8, 7, 6, 5, 12, 11, 10, 9]

看起来数据在 运行 秒之间按 ascending/descending 顺序排序。该行为的起源是 FIFO class 的方法 push_mul 中的行 objs.reverse()。不知道这个逻辑的推理是什么。注释掉该行后,每个 运行.

都可以获得相同的结果