【问题标题】:Class for calculating area and perimeter of rectangle and triangle - NameError用于计算矩形和三角形的面积和周长的类 - NameError
【发布时间】:2017-11-05 13:38:59
【问题描述】:

我从这段代码中得到一个错误,知道吗?看起来我的测试功能有些问题。我真的不明白这个。我刚开始使用类,在类中创建测试函数时有什么重要的事情需要处理吗?如果我不使用test_Rectangletest_Triangle 调用测试函数,代码似乎可以正常工作。尝试查看我的书和其他示例,但找不到任何解决此问题的方法。

Traceback (most recent call last):
  File "geometric_shapes.py", line 5, in <module>
    class Rectangle(object):
  File "geometric_shapes.py", line 31, in Rectangle
    test_Rectangle()
  File "geometric_shapes.py", line 19, in test_Rectangle
    r = Rectangle(3, 4, 2, 5)
NameError: name 'Rectangle' is not defined

代码:

# Exercise 7.4: Make classes for a rectangle and a triangle

from math import sqrt

class Rectangle(object):
    def __init__(self, x0, y0, w, h):
        self.x0 = x0
        self.y0 = y0
        self.w = w
        self.h = h

    def area(self):
        return self.h*self.w

    def perimeter(self):
        return 2*self.w + 2*self.h

    def test_Rectangle():
        r = Rectangle(3, 4, 2, 5)
        w = 2; h = 5
        expected_area = w*h
        computed_area = r.area()
        diff = abs(expected_area - computed_area)
        tol = 1E-14
        assert diff < tol, "bug in Rectangle.area, diff=%s" % diff

        expected_perimeter = 2*w + 2*h
        computed_perimeter = r.perimeter()
        diff = abs(expected_perimeter - computed_perimeter)
        assert diff < tol, "bug in Rectangle.perimeter, diff=%s" % diff
    test_Rectangle()


class Triangle(object):
    def __init__(self, v1, v2, v3):
        self.v1 = v1
        self.v2 = v2
        self.v3 = v3

    def area(self):
        x1, y1 = self.v1
        x2, y2 = self.v2
        x3, y3 = self.v3
        return 1/2*abs(x2*y3 - x3*y2 - x1*y3 + x3*y1 + x1*y1 - x2*y1)

    def perimeter(self):
        ver = (self.v1, self.v2, self.v3)
        AB = sqrt((ver[1][0] - ver[0][0])**2 + (ver[1][1] - ver[0][1])**2)
        BC = sqrt((ver[2][0] - ver[1][0])**2 + (ver[2][1] - ver[1][1])**2)
        AC = sqrt((ver[2][0] - ver[0][0])**2 + (ver[2][1] - ver[0][1])**2)
        perimeter = AB + BC + AC
        return perimeter

        def test_Triangle():
            t = Triangle((0,0), (1,0), (0,2))
            expected_area = 1
            computed_area = t.area()
            diff = abs(expected_area - computed_area)
            tol = 1E-14
            assert diff < tol, "bug in Triangle.area, diff=%s" % diff

            expected_perimeter = 5.236
            computed_perimeter = t.perimeter()
            diff = abs(expected_perimeter - computed_perimeter)
            assert diff < tol, "bug in Rectangle.perimeter, diff=%s" % diff
        test_Triangle()

【问题讨论】:

  • 请检查您的缩进
  • 您收到此错误是因为在您的类定义中调用test_Rectangle 时,Rectangle 显然尚未定义。您所做的与x = x +1 完全相同,x 之前未在您的代码中定义。此外,类不是函数或过程。您不应该在类定义期间运行函数,至少不应该这样。你需要一本更好的书来更好地理解 OOP。

标签: python class testing nameerror


【解决方案1】:

正如 jonsharpe 指出的那样,在 Rectangle 类中定义 test_Rectangle 函数时,您的缩进是错误的

以下程序将起作用。

编辑

之前我认为您已经从您的代码中提供了一小部分代码,这些代码复制了该问题,因此并不想过多地更改解决方案,但现在已经更新了答案。

更新

由于测试函数在类内部,并且由于没有类的实例化,也没有通过这些实例调用测试函数,因此没有调用函数。

在下面的代码中,我将您自己的函数移到了类定义之外并显式调用了它们。

from math import sqrt

class Rectangle(object):
    def __init__(self, x0, y0, w, h):
        self.x0 = x0
        self.y0 = y0
        self.w = w
        self.h = h

    def area(self):
        return self.h*self.w

    def perimeter(self):
        return 2*self.w + 2*self.h



class Triangle(object):
    def __init__(self, v1, v2, v3):
        self.v1 = v1
        self.v2 = v2
        self.v3 = v3

    def area(self):
        x1, y1 = self.v1
        x2, y2 = self.v2
        x3, y3 = self.v3
        return 1/2*abs(x2*y3 - x3*y2 - x1*y3 + x3*y1 + x1*y1 - x2*y1)

    def perimeter(self):
        ver = (self.v1, self.v2, self.v3)
        AB = sqrt((ver[1][0] - ver[0][0])**2 + (ver[1][1] - ver[0][1])**2)
        BC = sqrt((ver[2][0] - ver[1][0])**2 + (ver[2][1] - ver[1][1])**2)
        AC = sqrt((ver[2][0] - ver[0][0])**2 + (ver[2][1] - ver[0][1])**2)
        perimeter = AB + BC + AC
        return perimeter



def test_Rectangle():
    r = Rectangle(3, 4, 2, 5)
    w = 2; h = 5
    expected_area = w*h
    computed_area = r.area()
    diff = abs(expected_area - computed_area)
    tol = 1E-14
    assert diff < tol, "bug in Rectangle.area, diff=%s" % diff

    expected_perimeter = 2*w + 2*h
    computed_perimeter = r.perimeter()
    diff = abs(expected_perimeter - computed_perimeter)
    assert diff < tol, "bug in Rectangle.perimeter, diff=%s" % diff

def test_Triangle():
    t = Triangle((0,0), (1,0), (0,2))
    expected_area = 1
    computed_area = t.area()
    diff = abs(expected_area - computed_area)
    tol = 1E-14
    assert diff < tol, "bug in Triangle.area, diff=%s" % diff

    expected_perimeter = 5.236
    computed_perimeter = t.perimeter()
    diff = abs(expected_perimeter - computed_perimeter)
    assert diff < tol, "bug in Rectangle.perimeter, diff=%s" % diff

test_Triangle()
test_Rectangle()

看看这些 python 库来编写你的测试

Unit Test python 2

Unit Test python 3

【讨论】:

  • 谢谢,现在可以使用了。唯一的问题是我的测试功能在出现问题时不会激活。例如,如果我将 def_test_Triangle 下的 expected_area 设置为 3000,则没有任何反应。
  • test_Rectangle()test_Triangle() 永远不会被这样调用。
  • 想解释一下为什么?我按照我书中的确切信息进行操作。
  • @TheNarsisisst 如果这正是你的书告诉你要做的事情,你需要再买一个。但是要回答您的问题,它们不会被执行,因为测试函数是在return 语句之后定义并调用的。测试当然不应该在类中,它们应该是函数。
  • @martineau,是的,我确实知道这一点,但假设 OP 从您的代码中给出了一小部分代码,这些代码复制了该问题,因此不想过多地更改解决方案,但现在有了更新了答案。
猜你喜欢
  • 2017-11-21
  • 1970-01-01
  • 2016-01-17
  • 2023-01-30
  • 2019-10-06
  • 2020-06-15
  • 1970-01-01
  • 2023-01-31
  • 2010-10-07
相关资源
最近更新 更多