Python断言 isinstance() 向量

4

我正在尝试在Python中实现一个Vector3类。如果我要在C++或C#中编写Vector3类,我会将X、Y和Z成员存储为浮点数,但是在Python中,我了解到鸭子类型是最好的方法。因此,根据我的C++/C#知识,我编写了以下代码:

class Vector3:
    def __init__(self, x=0.0, y=0.0, z=0.0):
        assert (isinstance(x, float) or isinstance(x, int)) and (isinstance(y, float) or isinstance(y, int)) and \
               (isinstance(z, float) or isinstance(z, int))
        self.x = float(x)
        self.y = float(y)
        self.z = float(z)

这个问题涉及到断言语句:在这种情况下(用于数学中的Vector3实现),你会使用它们吗?我还将其用于类似的操作。
def __add__(self, other):
    assert isinstance(other, Vector3)
    return Vector3(self.x + other.x, self.y + other.y, self.z + other.z)

你在这些情况下会使用assert吗?根据这个网站:https://wiki.python.org/moin/UsingAssertionsEffectively,不应该过度使用assert,但对于像我这样一直使用静态类型的人来说,不检查相同数据类型是非常奇怪的。
1个回答

10

assert 被更好地用于调试而不是留在生产代码中。你可以为向量属性 xyz 创建属性,并在传递的值不符合要求的类型时引发 ValueError

class Vector3:
    def __init__(self, x=0.0, y=0.0, z=0.0):
        self.x = x
        self.y = y
        self.z = z

    @property
    def x(self):
        return self._x

    @x.setter
    def x(self, val):
        if not isinstance(val, (int, float)):
            raise TypeError('Inappropriate type: {} for x whereas a float \
            or int is expected'.format(type(val)))
        self._x = float(val)

    ...

注意 isinstance 函数还可以接受一个类型元组作为参数。

__add__ 运算符中,您还需要使用 raise TypeError 抛出一个适当的错误信息:

def __add__(self, other):
    if not isinstance(other, Vector3):
        raise TypeError('Object of type Vector3 expected, \
        however type {} was passed'.format(type(other)))
    ...

那么在这个例子中,您也会使用isinstance()而不是立即期望正确的类型吗? - Stefan B
@StefanB 你可以这样做,以防止用户传递其他数字类型,如复数类型。 - Moses Koledoye

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接