Search code examples
pythondesign-patternsinheritanceclass-variables

Python's Class Variables and Inheritance


I have here some code for a unit conversion program; it throws a NameError, because of Python's inheritance order.

class _Units :
    _metric_unit_names   = {'metric'}
    _standard_unit_names = {'standard'}

class TemperatureUnits (_Units) :
    _metric_unit_names.update({'celsius', 'c'})
    _standard_unit_names.update({'fahrenheit', 'f'})

TemperatureUnits()

I was wondering what the "best" technique for this situation would be. I could make _metric_unit_names and _standard_unit_names instance variables, but to make a new set on each instantiation seems wasteful. Also having a shared behavior seems optimal in this particular situation.


Solution

  • The best course of action is to not define the attributes as static attributes of the class. What you're after is something like this:

    class _Units :
        def __init__(self):
            self._metric_unit_names   = {'metric'}
            self._standard_unit_names = {'standard'}
    
    class TemperatureUnits (_Units) :
        def __init__(self):
            _Units.__init__(self)
            self._metric_unit_names.update({'celsius', 'c'})
            self._standard_unit_names.update({'fahrenheit', 'f'})
    
    TemperatureUnits()
    

    Defining attributes outside of __init__ cause them to be static members of the class (i.e. _Units._metric_unit_names). Defining them within init cause them to be attributes of a class instance (i.e. my_units_instance._metric_unit_names).