Python类对象和重新计算多个属性

2021-09-27 06:39:42 发布

您现在位置:Python中文网/ 问答频道 /正文

我几乎没有OO编程的经验,作为一个典型的工程师,我倾向于将函数代码拼凑在一起。然而,我正试图改变这一点,我看到了在建模物理世界时实现OO的价值。我写了我有史以来的第一堂课。我希望该类的一个实例能够存储位置的笛卡尔[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类和property函数了解有限,因此有更好的方法来实现这一点。我不知道xyzrθphi的方法是否需要完全编写,因为它们只是每个列表/数组中的元素,但无法解决这个问题。我也不知道这是否是构造类对象的最安全和最python的方法:

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数组替换,这样我就可以对向量执行代数,但现在我只想得到正确的类结构。你知道吗

谢谢你的帮助。你知道吗

克莱夫