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
class 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]'
The mass of Earth is: 5.97 [10^24 kg]
从根本上说,所有身体都有质量。但是,在此模拟的上下文中,确定质量的方法在class Body(object)
的各种子类之间有所不同,即:class Planet(Body)
,class Satellite(Body)
,等
class Planet(Body)
中,质量是通过Planet_Mass(name)
确定的,其中包括阅读行星事实表.txt文件。class Satellite(Body)
中,质量是通过Satellite_Mass(name)
确定的,其中包括阅读卫星情况说明书.txt文件。 无论如何都要改变我的子课程的初始化,以减少冗余?
基本上,我想删除在self.mass = Planet_Mass(name)
中陈述class Planet(Body)
的必要性。
答案 0 :(得分:3)
不要在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
如果您想进一步避免子类“if
中的__init__
语句,那么您可以在Body
类上放置所需的行为。基本思想是定义一个从名称中计算质量的方法。在基类上,此方法不执行任何操作。在您的子类上,它从查找表中获取质量。那么你的子类中甚至不需要__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
,因为通过名称查找正文的质量不需要访问实例(或类,就此而言)。