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()
。不知道这个逻辑的推理是什么。注释掉该行后,每个 运行.
都可以获得相同的结果
当我使用 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()
。不知道这个逻辑的推理是什么。注释掉该行后,每个 运行.