Reputation: 608
What I would like is the following:
lst = []
class Awesome:
"""This is my magical super class."""
...
class Inherits(Awesome):
"""Awesome does awesome stuff with Inherits."""
name = "Stack"
class InheritsAgain(Awesome):
name = "Overflow"
print(lst)
#: ['Stack', 'Overflow']
So basically, when the classes Inherits
and InheritsAgain
are defined, because they
inherit from Awesome
, Awesome
has some metaclass magic (or whatever), that reads
the attribute name
from the inheriting class, and appends it to lst
.
I've looked at the meta-classes in Python, but I'm not sure exactly how this would fit together.
Is this possible in Python? And if it is, how would you go about it?
Edit:
Let's add to the above example, so that this also works:
class AndAgain(Awesome):
name = "/root/path/<name>/<id>"
def go():
pass
I want the whole class AndAgain
to be defined, so that I can inspect and see that name
exists with the value "/root/path/<name>/<id>"
, and the function go()
also exists.
Upvotes: 1
Views: 81
Reputation: 69031
lst = []
class AwesomeMeta(type):
def __new__(metacls, cls, bases, classdict):
if cls != 'Awesome':
lst.append(cls)
return super().__new__(metacls, cls, bases, classdict)
class Awesome(metaclass=AwesomeMeta):
"""This is my magical super class."""
class Stack(Awesome):
"""Awesome does awesome stuff with Inherits."""
class Overflow(Awesome):
"""More awesomely stuff!"""
print(lst)
And to show looking inside the class:
lst = []
class AwesomeMeta(type):
def __new__(metacls, cls, bases, classdict):
if 'name' in classdict:
lst.append(classdict['name'])
return super().__new__(metacls, cls, bases, classdict)
class Awesome(metaclass=AwesomeMeta):
"""This is my magical super class."""
class Inherits(Awesome):
"""Awesome does awesome stuff with Inherits."""
name = 'Stack'
class InheritsAgain(Awesome):
"""More awesomely stuff!"""
name = 'Overflow'
class AndAgain(Awesome):
name = "/root/path/<name>/<id>"
def go():
pass
print(lst)
Upvotes: 2
Reputation: 4182
One can use metaclasses
class AwesomeMeta(type):
lst = []
def __new__(metacls, cls, bases, classdict):
if 'name' in classdict:
metacls.lst.append(classdict['name'])
return super(AwesomeMeta, metacls).__new__(metacls, cls, bases, classdict)
class Awesome(object):
"""This is my magical super class."""
__metaclass__ = AwesomeMeta
class Inherits(Awesome):
"""Awesome does awesome stuff with Inherits."""
name = 'Stack'
class InheritsAgain(Awesome):
"""More awesomely stuff!"""
name = 'Overflow'
print InheritsAgain.lst, Inherits.lst, Awesome.lst
or one can use __subclasses__
method
print [i.name for i in Awesome.__subclasses__()]
or One can use class decorator
lst = []
def cls_decorator(cls):
lst.append(cls.name)
return cls
@cls_decorator
class Awesome(object):
"""This is my magical super class."""
name = 'Awesome'
@cls_decorator
class Inherits(Awesome):
"""Awesome does awesome stuff with Inherits."""
name = 'Stack'
@cls_decorator
class InheritsAgain(Awesome):
"""More awesomely stuff!"""
name = 'Overflow'
Solution should depend on what are You going to do
Upvotes: 1