python - 如何在Python中根据子类类型定义基类参数?

标签 python python-2.7 class inheritance abstract-class

父类:class Body(object)

我有一个父类,描述了物理体的经典力学定义。事实上,这个父类具有以下属性:名称质量位置速度

from Utilities import *

class Body(object):

  '''
  In classical mechanics a physical body is collection of
  matter having properties including mass, velocity, momentum
  and energy. The matter exists in a volume of three-dimensional
  space called its extension.
  '''

  def __init__(self, name, mass):
    if isinstance(name, str) and isinstance(mass, float):
      #Name
      self.name = name
      #Mass
      self.mass = mass
      #Position record
      self.positions = np.empty(shape = (0, 3), dtype = float)
      #Velocity record
      self.velocities = np.empty(shape = (0, 3), dtype = float)
      pass
    else:
      raise TypeError('Name and mass must be string and float, respectivly.')
    return None

子类:类 Planet(Body)

此外,我有一个描述行星的子类,行星本质上是物理体,因此应该继承其抽象物理属性,即:名称质量位置速度

class Planet(Body):
  def __init__(self, name, mass = float):
    self.mass = Planet_Mass(name)
    Body.__init__(self, name, self.mass)

用法

#Import the necesary modules
from context import Planet
#Instantiate Earth as a massive celestial object
Earth = Planet('Earth')
#Print the mass of the planet [10^24 kg]
print 'The mass of Earth is: ', Earth.mass, ' [10^24 kg]'

结果

地球的质量为:5.97 [10^24 kg]

问题

从根本上来说,所有的物体都有质量。然而,在此模拟的上下文中,确定质量的方法在class Body(object)的各个子类之间有所不同,即:class Planet (Body)类卫星(Body)

  • Planet(Body) 类 中,质量 通过 Planet_Mass(name) 确定,其中涉及阅读行星情况说明书 .txt文件。
  • Satellite(Body) 类 中,质量 通过 Satellite_Mass(name) 确定,其中涉及阅读卫星资料表 .txt文件。

是否有办法改变我的子类的初始化以减少冗余?

本质上,我想消除在 class Planet(Body) 中声明 self.mass = Planet_Mass(name) 的必要性。

最佳答案

不要在 Planet 类构造函数中接受 mass,因为您不会使用它。

不要在 Planet 类构造函数中设置 self.mass,因为父构造函数会执行此操作。

class Planet(Body):
    def __init__(self, name):
        Body.__init__(self, name, Planet_Mass(name))

如果您确实想在 Planet 类中接受 mass 并允许它覆盖查找表中的质量(或者某些行星不在查找表中)表),这样做:

class Planet(Body):
    def __init__(self, name, mass=None):
        if mass is None:
            Body.__init__(self, name, Planet_Mass(name))
        else:
            Body.__init__(self, name, mass)

earth   = Planet("Earth")
trantor = Planet("Trantor", 1.792e25)   # Asimov's Trantor; ~3x Earth mass

如果您想更进一步并避免在子类的 __init__ 中使用 if 语句,那么您可以将所需的行为放在 Body 上类(class)。基本思想是定义一种方法来根据名称计算质量。在基类上,此方法不会执行任何操作。在您的子类上,它从查找表中获取质量。那么你的子类中甚至不需要 __init__

class Body(object):

     def __init__(self, name, mass=None):
         if mass is None:
             mass = self._name2mass(name)
         # followed by the argument checking and attribute setting
         # especially, you must check that mass is not None

     @staticmethod
     def _name2mass(name): return None

class Planet(Body):

     @staticmethod
     def _name2mass(name): return Planet_Mass(name)
     # or just implement Planet_Mass here!

我使用了@staticmethod,因为通过名称查找物体的质量不需要访问实例(或类,就此而言)。

关于python - 如何在Python中根据子类类型定义基类参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36653088/

相关文章:

c++ - 遍历指向类的指针 vector

Python 列表推导式 - 转置

python - 如何更改 xgboost.plot_importance 中绘图的大小?

python - 如何在没有强类型的情况下确保可靠的合约?

mysql - Pipeline 不写入 MySQL,但也没有给出错误

C++ Pascal 字符串错误。我在我的代码中找不到错误

python - 使用 django rest 框架的自定义 URL

python - tflearn.fully_connected 的第二个参数代表什么?

python - false 未定义

python - 连接作为 python 中的类实例属性的 numpy 数组