我对OO编程几乎没有经验,作为一名典型的工程师,我倾向于将功能代码整合在一起。但是,我正在尝试改变这一点,并且在建模物理世界时我看到了实施OO的价值。我写了我的第一堂课position vector。我希望类的实例能够存储位置的笛卡尔[x, y, z]
和极[z, theta, phi]
坐标。更新一个属性会自动更新其他属性。这个类稍后将通过合成在其他类中重用。
我希望我班级的一个实例执行以下操作:
>> p = PositionVector([15,5,5])
>> p.cartesian
[15,5,5]
>> p.polar
[16.583123951777, 0.0, 1.2645189576252271]
>> p.x = 3
>> p.cartesian
[3,5,5]
>> p.polar
[7.681145747868608, 0.7853981633974483, 0.8619682853367363]
>> p.theta = 0.5
>> p.cartesian
[5.117141702137862, 2.7955072527614058, 5.0]
>> p.polar
[7.681145747868608, 0.5, 0.8619682853367363]
到目前为止我写的课程在下面,但我对python类的理解有限,而属性函数告诉我有更好的方法。我不知道 xyzr theta 和 phi 的方法是否需要完全写入,因为它们只是每个列表/数组中的元素,但无法弄清楚如何绕过这个。我也不知道这是否是构建类对象最安全,最pythonic的方式:
class PositionVector(object):
def __init__(self, vector, system='cartesian'):
if system == 'cartesian':
self.cartesian = vector
self.polar = self.position_vector_polar(self.cartesian)
if system == 'polar':
self.polar = vector
self.cartesian = self.position_vector_cartesian(self.polar)
@property
def cartesian(self):
return self._cartesian
@cartesian.setter
def cartesian(self, value):
self._cartesian = value
self._polar = self.position_vector_polar(self._cartesian)
self._x, self._y, self._z = self._cartesian
self._r, self._theta, self._phi = self._polar
@property
def polar(self):
return self._polar
@polar.setter
def polar(self, value):
self._polar = value
self._cartesian = self.position_vector_cartesian(self._polar)
self._x, self._y, self._z = self.cartesian
self._r, self._theta, self._phi = self.polar
@property
def x(self):
return self._x
@x.setter
def x(self, value):
self._x = value
self._cartesian[0] = self._x
self._polar = self.position_vector_polar(self._cartesian)
# repeat above for y and z variables
@property
def r(self):
return self._r
@r.setter
def r(self, value):
self._r = value
self._polar[0] = self._r
self._cartesian = self.position_vector_cartesian(self._polar)
# repeat above for thets and phi variables
def position_vector_cartesian(self, polar):
r, theta, phi = polar
x = r * math.cos(theta) * math.sin(phi)
y = r * math.sin(theta) * math.sin(phi)
z = r * math.cos(phi)
return [x, y, z]
def position_vector_polar(self, cartesian):
x, y, z = cartesian
r = math.sqrt(x ** 2 + y ** 2 + z ** 2)
theta = math.atan(y/x)
phi = math.acos(z/r)
return [r, theta, phi]
请注意,列表将被numpy数组替换,因此我可以对向量执行代数,但是现在我只想让类结构正确。
感谢您的帮助。
克里夫