如何创建一个可以用x和y或角度(度数)初始化的二维向量对象?

1 投票
4 回答
1780 浏览
提问于 2025-04-17 17:54

我想在Python中初始化我的向量对象时,可以选择用一个角度或者用x和y来进行初始化。我知道可以通过math.atan2(x, y)来计算角度,也可以通过角度来算出xy,但我不知道怎么让这些输入变成可选的。

我希望能够这样调用:

Vector(x, y, speed)

或者这样:

Vector(angle, speed)

谢谢!

4 个回答

1

作为一种替代方案,我会使用类的方法,这样构造函数只需要接收字段作为参数。

class Vector(object):
    __slots__ = ['x', 'y']
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __repr__(self):
        return 'Vector({}, {})'.format(self.x, self.y)

    @classmethod
    def polarVector(cls, angle, mag):
        return cls(math.cos(angle) * mag, math.sin(angle) * mag)

    @classmethod
    def magVector(cls, x, y, mag):
        a = mag / math.sqrt(x**2 + y**2)
        return cls(x * a, y * a)

可选参数的问题

可选参数最大的一个问题就是代码的清晰度。

a = Vector(1, 2)             # Is 1 "angle" or "x"?
a = Vector(3, 4, 10)         # Huh?

# These functions do different things,
# so it makes sense that they have different names.
a = Vector.polarVector(1, 2)
a = Vector.magVector(3, 4, 10)
2

我觉得最符合Python风格的方法是添加一个类方法

class Vector:
    def __init__(x, y, speed):
        ...

    @classmethod
    def from_angle(cls, angle, speed):
        # figure out x and y from angle
        return cls(x, y, speed)

然后可以调用Vector(x, y, speed)或者Vector.from_angle(angle, speed)

 

像这样的一些变体:

def __init__(first, second, third=None)
   ...

或者

def __init__(*args):
   ...

会让代码变得不够清晰。使用你代码的人(包括未来的你)会很难快速浏览方法的签名,看到他们的选择。

2
class Vector(object):
    """
    >>> Vector(angle, speed)  # initialize with angle and speed
    >>> Vector(x, y, speed)   # or initialize with x, y, and speed
    """
    def __init__(first, second, third=None):
        if third is None:
            angle, speed = first, second
        else:
            x, y, speed = first, second, third

如果用两个参数来调用,third 默认会是 None。这样的话,前两个参数会被赋值给 anglespeed。如果不是这样,参数就会被赋值给 xyspeed

(编辑:添加了文档字符串,这样 Vector 的调用方式就清楚了。)

撰写回答