首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当结果相等时Python失败(Pythonv3.6)

当结果相等时Python失败(Pythonv3.6)
EN

Stack Overflow用户
提问于 2018-08-17 15:01:11
回答 2查看 2.4K关注 0票数 6

因此,我对unittest结果失败有一个问题,因为测试声称assertEqual语句失败了。

错误码:

代码语言:javascript
复制
AssertionError: {1: ((51, 98), (31, 4)), 2: ((51, 98), (49, 80)), 3: ((31, 4), (49, 80))} != {1: ((51, 98), (31, 4)), 2: ((51, 98), (49, 80)), 3: ((31, 4), (49, 80))}

下面是最简单的代码:

代码语言:javascript
复制
class InstanceTestCase(unittest.TestCase):

    def setUp(self):
        self.prob = Generate.populated_instance(3, 12345678)

        node_one = Node(51, 98)
        node_two = Node(31, 4)
        node_three = Node(49, 80)

        edge_one = Edge(node_one, node_two)
        edge_two = Edge(node_one, node_three)
        edge_three = Edge(node_two, node_three)

        self.comparison_edges = {1: edge_one, 2: edge_two, 3: edge_three}

    def test_Instance(self):
        self.assertEqual(self.prob.edges, self.compare_edges_dict)  # returning an error

正在测试这些类:

代码语言:javascript
复制
class Node:
    """Represents the nodes as points with a position x, y."""

    def __init__(self, x=0, y=0):
        """Create a new node at x, y."""
        self.x = x
        self.y = y

    def __str__(self):
        return "({0}, {1})".format(self.x, self.y)

    def __repr__(self):
        return str(self)

    def __eq__(self, other):
        if type(self) == type(other):
            return self.x == other.x and self.y == other.y
        else:
            raise TypeError

    def __hash__(self):
        return hash((self.x, self.y))


class Edge:
    """Represents the edges as having a length and being bounded by two points."""
    def __init__(self, node_one, node_two):
        """Create an edge using two nodes."""
        self.node_one = node_one
        self.node_two = node_two

    def __str__(self):
        return "({0}, {1})".format(self.node_one, self.node_two)

    def __repr__(self):
        return str(self)


class Instance:

    count = 0

    def __init__(self, node_count=0, seed=0, nodes=None, edges=None, solution_path=None, solve_time=0):
        """Create a new problem with x number of nodes.
        Leave seed blank for random seed, otherwise put an eight digit number to use for the seed."""
        self.node_count = node_count
        self.seed = seed
        self.nodes = nodes
        self.edges = edges
        self.solution_path = solution_path
        self.solve_time = solve_time
        Instance.count += 1

    # makes outputs from print easier to read
    def __str__(self):
        return "ID: {0}\n" \
               "Node count: {1}\n" \
               "Seed: {2}\n" \
               "Nodes: {3}\n" \
               "Edges: {4}\n" \
               "Solve time: {5}".format(self.problem_id,
                                        self.node_count,
                                        self.seed,
                                        self.nodes,
                                        self.edges,
                                        self.solve_time)

    def __repr__(self):
        return str(self)

测试代码中创建的prob对象是Instance类的一个实例,其中包括两个字典(在方法调用之后),一个用于节点,另一个用于边缘。使用populated_instance类的Generate方法生成节点,并在populated_instance方法中通过不同的方法调用从节点生成边缘。

prob.edges字典如下所示:

代码语言:javascript
复制
{1: ((51, 98), (31, 4)), 2: ((51, 98), (49, 80)), 3: ((31, 4), (49, 80))}

并由包含在Node类实例中的Edge类的实例组成。正如您在上面最简单的代码中所看到的,我使用相同的对象和相同的值创建了一个等价的字典。

因此,我确信prob.edges字典和comparison_edges字典是完全相同的,完全由正确实例化的类对象组成,并且我没有将任何这些对象与看起来像对象的字符串进行比较。

我发现了类似的问题:Python unittest failure when results appear equal.然而,它并没有说明我的问题。

一个多小时后,我终于意识到发生了什么,这是一个完全不同的问题。所以我也要发布我的问题和答案。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-08-17 15:01:11

在我的例子中,答案是我没有在我的__eq__()类中实现一个Edge方法。

该方法将由其他一些方法自动调用,如果它没有在类中实现,那么需要等式检查的方法可能无法正常工作。

我的Edge类最初看起来如下所示:

代码语言:javascript
复制
class Edge:
    """Represents the edges as having a length and being bounded by two points."""
    def __init__(self, node_one, node_two):
        """Create an edge using two nodes."""
        self.node_one = node_one
        self.node_two = node_two

    def __str__(self):
        return "({0}, {1})".format(self.node_one, self.node_two)

    def __repr__(self):
        return str(self)

包括这个之后..。

代码语言:javascript
复制
    def __eq__(self, other):
        if type(self) == type(other):
            return self.node_one == other.node_one and self.node_two == other.node_two
        else:
            raise TypeError

assertEqual中使用的等式检查效果很好。

(注意:我已经在我的__eq__()类中实现了一个重写的Node方法,并且测试证实,删除该方法也破坏了上面的检查。)

从python (https://docs.python.org/2/library/unittest.html)中可以看到这一点:

assertEqual(first, second, msg=None)测试第一和第二是相等的。如果值不相等,则测试将失败。 此外,如果第一和第二种类型与列表、元组、迪克、set、frozenset或unicode的类型完全相同,或者子类使用addTypeEqualityFunc()注册的任何类型,则将调用类型特定的相等函数,以生成更有用的默认错误消息(还请参见特定类型方法的列表)。 在2.7版本中更改:添加了类型特定的相等函数的自动调用。

在我看来,对自定义类调用的是“特定于类型的等式函数”,因此,如果不存在自定义__eq__()方法,则检查将失败。

详情请参阅下面@Humbalan的答案:)

票数 2
EN

Stack Overflow用户

发布于 2018-08-17 15:16:37

如果没有自己的__eq__()方法,Python只会比较对象的ID,当然它们并不相等。如果要测试不同对象属性的相等性,则需要__eq__()方法。事实上,你可以用这种方法来比较你想要的任何东西。我有一个例子,其中平等被定义为五个属性中的两个相等。其余三个属性没有得到考虑。

顺便提一下:在您的__eq__()方法中,您也应该检查对象类型的相等性。想象两个不同类的实例,它们具有相同的属性.

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51898138

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档