Accessing super(parent) class variable in python
super
helps you get the parent class when you have an instance of it. As far as I know, there's no easy way to do this at the class level without an instance, like you're trying to do. The only way I could think of to do this is to refer to the parent class explicitly:
class Child(Parent):
__props__ = Parent.__props__ + ...
To clarify a bit further, there's two basic problems:
super()
is syntactic sugar forsuper(Child, self)
, or more generally,super(type(self), self)
. Since there is noself
where you're using it, it doesn't make sense.- Even the class
Child
doesn't exist at the point thatsuper()
is getting called. It's still in the process of being defined, and so it would be invalid syntax to even havesuper(Child, self)
(go ahead and try it, I can wait), becauseChild
isn't a thing yet.
As such, you'll need to explicitly refer to the parent class, like I show above.
You could define an __init_subclass__
method of the Parent
class that initializes Child.__props__
. This method is called every time a subclass of of Parent
is created, and we can use it to modify the __props__
that class inherits with an optional __props__
argument passed as part of the class definition.
class Parent:
__props__ = (('a', str, 'a var'), ('b', int, 'b var'))
def __init_subclass__(cls, __props__=(), **kwargs):
super().__init_subclass__(**kwargs)
cls.__props__ = cls.__props__ + __props__
class Child(Parent, __props__=(('c', str, 'foo'),)):
pass
print(Child.__props__)
# (('a', <class 'str'>, 'a var'), ('b', <class 'int'>, 'b var'), ('c', <class 'str'>, 'foo'))
class GrandChild(Child, __props__=(('d', float, 'd var'),)):
pass
print(GrandChild.__props__)
# (('a', <class 'str'>, 'a var'), ('b', <class 'int'>, 'b var'),
# ('c', <class 'str'>, 'foo'), ('d', <class 'float'>, 'd var'))
A bit late to the party but this is a job for metaclasses:
class Parent(object):
__props__ = (
('a', str, 'a var'),
('b', int, 'b var')
)
def __init__(self):
self.test = 'foo'
class AddPropsMeta(type):
def __init__(cls, name, bases, attrs):
cls.__props__ = sum((base.__props__ for base in bases), ()) + cls.__props__
super().__init__(name, bases, attrs)
class Child(Parent, metaclass=AddPropsMeta):
__props__ = (
('c', str, 'foo'),
)
>>> Child.__props__
(('a', str, 'a var'), ('b', int, 'b var'), ('c', str, 'foo'))