1

我希望能够在 python 中使用角度或 x 和 ay 初始化我的 Vector 对象。我知道我可以使用计算出角度,math.atan2(x, y)并且可以使用计算出角度xy角度,但我不知道如何使这些输入成为可选。

我希望能够致电:

Vector(x, y, speed)

或者:

Vector(angle, speed)

谢谢!

4

4 回答 4

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

如果使用两个参数调用,thirdNone默认为。所以前两个参数将被分配给anglespeed。否则,参数将分配给x,yspeed

(编辑:添加了一个文档字符串,因此Vector' 的调用签名很清晰。)

于 2013-03-04T20:12:12.450 回答
2

我认为最 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):
   ...

失去太多清晰度。使用您的代码的人(包括未来的您)将无法浏览方法签名并查看他们的选项。

于 2013-03-04T20:14:50.323 回答
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)
于 2013-03-04T20:17:56.960 回答
0

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)
于 2013-03-04T20:18:28.333 回答