1

I'm working on a library that provides (1) a class decorator to automatically store certain attributes to a file and (2) a function to patch the same behavior into existing instances.

Implementation of the class decorator is fairly simple:

def store_instances(path, attrs):
    def decorator(cls):
        class Decorated(cls, StorageBehavior):
            _path = path
            _attrs = attrs
        return Decorated
    return decorator

but for the function, what's the best way to add behavior from a base class into an existing object? Searching for "dynamically changing base classes" yields this question, but the answers are essentially "don't do that and/or it's not possible". Is there a better way to this?

Community
  • 1
  • 1
Jace Browning
  • 11,699
  • 10
  • 66
  • 90
  • 2
    Why are you decorating, rather than just using `SpecialBehavior` as an explicit mix-in? And *what* "special behaviour" are you trying to patch in? – jonrsharpe Sep 12 '14 at 13:33
  • 1
    Class decorators used this way have a nasty habit of breaking `super`. . . I think @jonrsharpe is on the right track. Just have the user mix it in themselves (it's no harder than having them add a decorator) – mgilson Sep 12 '14 at 13:36
  • "special behavior" = storing certain attributes to a file I'm using a decorator because it requires less modification to exiting code and I can pass arguments to the decorator such as which attributes I care about and where to store them. – Jace Browning Sep 12 '14 at 13:36
  • 2
    Could you provide a less abstract example of what you're trying to achieve? It's difficult to make helpful suggestions in such a general sense. – jonrsharpe Sep 12 '14 at 13:39
  • @jonrsharpe is that more clear? – Jace Browning Sep 12 '14 at 13:44
  • It's an improvement, but it's still not clear what the behaviour you are trying to add is, or what `StorageBehaviour` does. Also from [PEP-0008](http://legacy.python.org/dev/peps/pep-0008/#descriptive-naming-styles) on leading and trailing double underscores: *"Never invent such names; only use them as documented."* – jonrsharpe Sep 12 '14 at 14:10
  • @jonrsharpe I removed the double underscores; they're not relevant to my question. – Jace Browning Sep 12 '14 at 14:14

1 Answers1

0

This achieves the same effect as the class decorator:

def store(instance, path, attrs):

    class Decorated(instance.__class__, StorageBehavior):
        _path = path
        _attrs = attrs

    instance.__class__ = Decorated

    return instance
Jace Browning
  • 11,699
  • 10
  • 66
  • 90