我希望能够在 python 中使用角度或 x 和 ay 初始化我的 Vector 对象。我知道我可以使用计算出角度,math.atan2(x, y)
并且可以使用计算出角度x
和y
角度,但我不知道如何使这些输入成为可选。
我希望能够致电:
Vector(x, y, speed)
或者:
Vector(angle, speed)
谢谢!
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
' 的调用签名很清晰。)
我认为最 Pythonic 的方法是添加一个类方法:
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):
...
失去太多清晰度。使用您的代码的人(包括未来的您)将无法浏览方法签名并查看他们的选项。
作为替代方案,我会使用类方法来完成,因此构造函数只会将字段作为参数。
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)
unutbu 和 Pavel Anossov 的两个答案都非常好。
我个人更喜欢将坐标作为元组传递(因为它们毕竟是一个向量并且属于一起)。因此,您将始终有两个参数:
#! /usr/bin/python3.2
import math
class Vector:
def __init__ (self, direction, speed):
self.speed = speed
try: self.angle = math.atan2 (direction [0], direction [1] )
except: self.angle = direction
v1 = Vector (math.pi / 4, 100)
print (v1.angle)
v2 = Vector ( (1, 1), 100)
print (v2.angle)