What is the best way for a class to reference itself in a class attribute?
Use a meta class to automatically set it.
def my_meta(name, bases, attrs):
cls = type(name, bases, attrs)
cls.bar = cls
return cls
class Foo(object):
__metaclass__ = my_meta
>>> print Foo.bar
<class '__main__.Foo'>
You can use a class decorator
def moi(fieldname):
def _selfref(cls):
setattr(cls, fieldname, cls.__name__)
return cls
return _selfref
usage:
@moi('bar')
class Foo(object):
pass
then:
>>> print Foo.bar
Foo
You could define a class decorator that replaced placeholder strings with the class being defined:
def fixup(cls):
placeholder = '@' + cls.__name__
for k,v in vars(cls).items():
if v == placeholder:
setattr(cls, k, cls)
return cls
@fixup
class Foo(object):
bar = '@Foo'
print('Foo.bar: {!r}'.format(Foo.bar)) # -> Foo.bar: <class '__main__.Foo'>
Another alternative would be to use the __init_subclass__()
special method which was introduced in Python 3.6 to create a base class and then derive your class from it instead of the generic object
:
class Base(object):
def __init_subclass__(cls, /, **kwargs):
super().__init_subclass__(**kwargs)
cls.bar = cls
class Foo(Base):
pass
print('Foo.bar: {!r}'.format(Foo.bar)) # -> Foo.bar: <class '__main__.Foo'>
You can use metaclasses. Define a __new__
which iterates over set attributes and then sets the back pointer to the class itself.