What is the best way to refer to a class name in a class attribute?

Unfortunately, in Python, a class attribute cannot refer to its class name. The following calls the nameerror:

class Foo(object): bar = Foo 

In a situation where a class attribute must refer to its class name (in my case, its part of the validation scheme for the library), what is the clearest way to do this?

My next attempt:

 class Foo(object): bar = None Foo.bar = Foo 

This works, but it can be confusing even with comments, since you expect the class attribute to be initialized when the declaration is made, and not after the class is declared.

Does anyone have a better workaround?

+5
source share
5 answers

You can define a class decorator that replaces 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'> 
+2
source

You can use metaclasses . Define __new__ that __new__ over the given attributes and then sets the back pointer to the class itself.

+1
source

You can use class decorator

 def moi(fieldname): def _selfref(cls): setattr(cls, fieldname, cls.__name__) return cls return _selfref 

using:

 @moi('bar') class Foo(object): pass 

then

 >>> print Foo.bar Foo 
+1
source

Use the meta class to set it automatically.

 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'> 
+1
source

Why not use a property if you just want the `` alias '' __class__ ?

 @property def bar(self): return self.__class__ 

This suggests that it is related to creating problems if you play with some inheritance.

0
source

Source: https://habr.com/ru/post/1237516/


All Articles