Nic*_*mer 17 python static-methods design-patterns class
我有一个包含许多类的Python模块,每个类代表具有其属性的特定物理材料(例如,密度,比热).一些属性只是float类的成员,但很多属性依赖于某些参数,例如温度.我通过@staticmethods 实现了这一点,即所有类看起来都像
class Copper(object):
magnetic_permeability = 1.0
@staticmethod
def density(T):
return 1.0 / (-3.033e-9 + 68.85e-12*T - 6.72e-15*T**2 + 8.56e-18*T**3)
@staticmethod
def electric_conductivity(T, p):
return 1.0141 * T**2 * p
@staticmethod
def specific heat(T):
return ...
class Silver(object):
...
class Argon(object):
...
...
Run Code Online (Sandbox Code Playgroud)
因此,Classes仅仅充当所有数据的容器,并且@staticmethods 的丰富性让我怀疑这个用例可能有更合适的设计模式.
任何提示?
我怀疑一个更合适的结构是拥有一个Material类,它将函数或系数作为参数,例如
class Material(object):
def __init__(self, mag_perm, density_coeffs, ...):
self.mag_perm = mag_perm
self._density_coeffs = density_coeffs
...
def density(self, T):
x0, x1, x2, x3 = self._density_coeffs
return 1.0 / (x0 + (x1 * T) + (x2 * (T ** 2)) + (x3 * (T ** 3)))
Run Code Online (Sandbox Code Playgroud)
然后,每种材料为每个计算出的参数提供自己的系数:
copper = Material(1.0, (-3.033e-9, 68.85e-12, 6.72e-15, 8.56e-18), ...)
copper.density(300)
Run Code Online (Sandbox Code Playgroud)
如果您需要更复杂的关系(例如,不同的计算),您可以使用子类Material和过载适当的计算.
您可以命名模块copper并创建所有这些作为模块级函数,然后单击import copper; copper.density(0)。
但是,如果有人这样做了from copper import density,而您cobalt又有一个名为的模块,另一个名为carbon,另一个称为,chlorine等等,都具有各自的density功能,该怎么办?哦哦
由于我们都同意成年人,因此您可以对此进行记录,并希望您的用户足够了解,只需导入该模块即可。或者您可以采取您的方法;在这种情况下,我会考虑将所有元素放在一个名为的模块中elements,然后用户可以from elements import Copper。静态方法将是适当的。