Build object with different input, using super-class and sub-class style, Python 3 I want to model a object of air, the temperature of which can be given in 3 different ways:


if the value is known (assuming the temperature is a constant)
if a curve of the values with different time is known (using interpolation)
if the formula of the temperature vs time is known.


My code is below:

from script.interpolate import interp1d
from importlib import import_module

class Air1:
    # case 1: temperature, which is a constant value, is given in the input.
    def __init__(self, meta: dict):
        self.city = meta['city']
        self.temperature = meta['temperature']

class Air2(Air1):
    # case 2: a curve of temperature vs time is given in meta.
    # times is a list, temperatures is a list.
    # so self.get_temperature is an interpolated function.
    # To get a new temperature, I can use new_temp = self.get_temperature(new_time)
    def __init__(self, meta: dict):
        super().__init__(meta=meta)
        times = meta['times']
        temperatures = meta['temperatures']
        self.get_temperature = interp1d(times, temperatures)

class Air3(Air1):
    # case 3: the formula to calculate temperature from time is known.
    # this formula is implemented in a python file called file_of_fomurla.
    # so self.get_temperature is an imported function.
    # To get a new temperature, I can use new_temp = self.get_temperature(new_time)
    def __init__(self, meta: dict):
        super().__init__(meta=meta)
        file_of_formula = meta['file_of_formula']
        self.get_temperature = import_module(file_of_formula + '.my_function')


One thing I have noticed in my code is that .temperature should only be in Air1, since Air2 and Air3 both just have a function to calculate temperature value based on time. However, like in my code, Air2 and Air3 are sub classes of Air1, but their input meta will not have the key 'temperature'. So this is an error.

Do you have any better way to implement the physics behind into the model. Maybe using some abstract class?
As you yourself have noted, the inheritance isn't benefiting you at all. Just write one class.

Passing meta as a dict is unidiomatic. Use **kwargs or parameters with defaults instead.

Consider dropping the get_… prefix.

Also consider passing the formula as code (e.g. a lambda) rather than referencing a module by name.

from script.interpolate import interp1d
from importlib import import_module

class Air:
    def __init__(self, city, **kwargs):
        self.city = city
        self.temperature = (
            lambda time: kwargs['temperature'] if 'temperature' in kwargs else
            interp1d(kwargs['times'], kwargs['temperatures']) if 'times' in kwargs else            
            import_module(kwargs['file_of_formula'] + '.my_function') if 'file_of_formula' in kwargs else
            kwargs['formula']
        )