Can you dynamically add class variables to subclass python?
<p>I have a large amount of auto-generated classes in python that essentially represent enums for part of a communication protocol, they look like so</p>

<pre><code># definitions.py

class StatusCodes(ParamEnum):
    Success = 1
    Error = 2
    UnexpectedAlpaca = 3

class AlpacaType(ParamEnum):
    Fuzzy = 0
    ReallyMean = 1

# etc etc etc
</code></pre>

<p>Defining things this way makes it easy for the auto-generator and also for humans to modify. The ParamEnum class provides all the functionality, get/setting, comparison, conversion and creation from the incoming network data and etc.</p>

<p>However, these classes require some extra meta-data. I do <em>not</em> want to add this into the source definition of each class though, as it makes it less readable and will break the autogenerator</p>

<p>At the moment I am doing it like this</p>

<pre><code># param_enum.py

class ParamEnum(object):
    def __init__(self):
        self.__class__._metadata = get_class_metadata(self.__class__)
</code></pre>

<p>however that strikes me as somewhat inefficient, since this will happen every time we instantiate one of these Enums (which happens often), not just on definition (the metadata does not change, so it only needs to be set once)</p>

<p>I tried added this to the bottom of the definition file, but ran into problems there too.</p>

<pre><code>class StatusCodes(ParamEnum):
    Success = 1
    Error = 2
    UnexpectedAlpaca = 3

for var in locals():  # or globals? 
    add_metadata(var)
    #doesn't work because it is in the same file, modifying dict while iteratng
</code></pre>

<p>Is there a way in python of overriding/adding functionality to when the class is defined, that can be inherited to subclasses? Ideally I'd like something like</p>

<pre><code>class ParamEnum(object):
    def __when_class_defined__(cls):
        add_metadata(cls)
</code></pre>

<p>Use a class decorator</p>

<pre><code>def add_metadata(cls):
    cls._metadata = get_class_metadata(cls)
    return cls

@add_metadata
class StatusCodes(ParamEnum):
    Success = 1
    Error = 2
    UnexpectedAlpaca = 3
</code></pre>

<p>What you want to do is in fact the very motivation to have decorators: The modification of a class or function after it has been created.</p>

<p>If you are unfamiliar with decorators, please read <a href="http://stackoverflow.com/a/1594484/4806820">this</a> (although it's a bit lengthy).</p>

<p>You could also use metaclasses, but they introduce more complexity than a decorator. If you want to avoid the additional decoration line <code>@add_metadata</code> and you think it is redundant with respect to the specified subclass <code>ParamEnum</code>, you could also make <code>_metadata</code> <a href="https://docs.python.org/3/howto/descriptor.html#descriptor-protocol" rel="nofollow">a descriptor</a> with lazy evaluation within the base class <code>ParamEnum</code>.</p>

<pre><code>class MetadataDescriptor(object):
    def __get__(self, obj, cls):
        if cls._metadata_value is None:
            cls._metadata_value = get_class_metadata(cls)
        return cls._metadata_value

class ParamEnum(object):
    _metadata_value = None
    _metadata = MetadataDescriptor()
</code></pre>

python inheritance