I have 2 classes A and B:
class A(object):
x = 0
class B(object):
y = 0
How can I make it so B "inherits" A's class-level variables (x in this case) by using decorators? Is it at all possible? The desired behavior (if possible), after decorated, B would look like this:
class B(object):
x = 0
y = 0
Note: If anyone wants/needs to know why I'm asking this, it's simply to make SQLAlchemy's Concrete Table Inheritance look nicer in code, although I can see many use cases for such behavior.
Sure you can; you can use a class decorator that takes class A as an argument, then updates the decorated class for you:
import types
class copyattributes(object):
def __init__(self, source):
self.source = source
def __call__(self, target):
for attr, value in self.source.__dict__.items():
if attr.startswith('__'):
continue
if isinstance(value, (property, types.FunctionType)):
continue
setattr(target, attr, value)
return target
The decorator copies anything that is really an attribute (not a function or a property), and doesn't start with a double underscore.
Usage:
class A(object):
x = 0
@copyattributes(A)
class B(object):
y = 0
Tested on the prompt:
>>> class A(object):
... x = 0
...
>>> @copyattributes(A)
... class B(object):
... y = 0
...
>>> B.y
0
>>> B.x
0
>>> dir(B)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'x', 'y']
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With