ベクトル オブジェクトを Python で角度または x と y のいずれかで初期化できるようにしたいと考えています。を使用して角度を把握でき、角度からと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
2 つの引数で呼び出された場合、デフォルトでthird
になりNone
ます。angle
したがって、最初の 2 つの引数はとに割り当てられ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とPavelAnossovの両方の答えはとても良いです。
私は個人的に座標をタプルとして渡すことを好みます(結局のところ、それらはベクトルであり、一緒に属しているため)。したがって、常に2つの引数があります。
#! /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)