如何创建一个可以用x和y或角度(度数)初始化的二维向量对象?
我想在Python中初始化我的向量对象时,可以选择用一个角度或者用x和y来进行初始化。我知道可以通过math.atan2(x, y)
来计算角度,也可以通过角度来算出x
和y
,但我不知道怎么让这些输入变成可选的。
我希望能够这样调用:
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
。这样的话,前两个参数会被赋值给 angle
和 speed
。如果不是这样,参数就会被赋值给 x
、y
和 speed
。
(编辑:添加了文档字符串,这样 Vector
的调用方式就清楚了。)