Defining a staticmethod is virtually always a mistake. Python has functions, so you'd always just define a module-level function. (You'd have copper.py
and inside of it have a plain old def density(T):
instead of using a staticmethod.)
That is to say, copper.py
would look like
magnetic_permeability = 1.0
def density(T):
return 1.0 / (-3.033e-9 + 68.85e-12*T - 6.72e-15*T**2 + 8.56e-18*T**3)
def electric_conductivity(T, p):
return 1.0141 * T**2 * p
def specific heat(T):
return ...
In this particular case, do you actually have multiple materials? If so, then you probably want them to be instances, not classes or modules. If you e.g., don't want them all to have the same rational cubic form for the thermal density dependence, you can make a subclass and have an instance of that or you can make a class that accepts functions as arguments.
class Material(object):
def __init__(self, density, electric conductivity):
self.density = density
self.electric_conductivity = electric_conductivity
copper = Material(
density=lambda T: 1.0 / (-3.033e-9 + 68.85e-12*T -
6.72e-15*T**2 + 8.56e-18*T**3),
electric_conductivity=lambda T, p: 1.0141 * T**2 * p
)
You can also make a metaclass if you want to maintain a declarative style.
By the way
class Copper():
def __init__(self):
self.magnetic_permeability = 1.0
...
probably doesn't do what you want to. This makes magnetic_permeability
only accessible in an instance of copper
. I don't recommend using classes rather than instances or modules for this, but if you did, you'd need to do
class Copper(object):
magnetic_permeability = 1.0
...
to be able to do Copper.magnetic_permeability
Note that I'm inheriting with object so that we're using Python 2 "new style classes". The changes are subtle, but it's nicer if you just ensure you'll never run into them.