Python - Get class name as variable inside Class declaration

Hey there,

Do you know if it’s possible to dynamically querry a class name from inside the class definition?
This would be usefull to create snippets in VSCode and avoid forgetting to change the super call.

Something like this:

class Real_class_name(Super_class):
    
    def __init__(self):
        getClassName = ???
        super(getClassName, self).__init__()
        ...

Where ??? would be a function that returns 'Real_class_name'

Because of Maya, I have to work with Python 27, but I’d be interested to know if this exists in either version of Python.

Thanks

className = type(self).__name__

1 Like

The super call is needed when you need to override a sub class of a base class whose machinery needs to be supported. On the super call you’re not providing a string but the class itself otherwise you’d hit a type error aka:

TypeError: super() argument 1 must be type, not ...

As the bound instance self has a member variable to its class (create via the __new__ magic method) you don’t need to use type inference:

class SubClass(BaseClass):
   def __init__(self):
      super(self.__class__, self).__init__()

python 3 makes it easier :slight_smile:

super().__init__() 
1 Like
  super(self.__class__, self) 

can lead to infinite recursion errors: https://stackoverflow.com/questions/18208683/when-calling-super-in-a-derived-class-can-i-pass-in-self-class. Unfortunately, you typically want to just hardcode the class argument in py2; in 3 you don’t need to do that and can just do super()

2 Likes

Ah yes! @Theodox - Just tested in repl.it even with derived classes that have it hardcoded the MRO will hit the base class and recursively loop e.g.

class Foo(object):
   pass

class Boo(Foo):
   def __init__(self):
     super(self.__class__, self).__init__() # will work

class Baz(Boo):
   def __init__(self):
     super(Baz, self).__init__() # Derived class we create recursion error. 

Python 3 ftw!

I guess it’s safer to keep writing the whole class name then. Really interesting, thanks!

careful: type(self).__name__ seems to returns the name of the actual class called by the instance, even if it is only declared in the super class.

class A(object):
  def __init__(self):
    self.name = type(self).__name__

class B(A):
  def __init__(self):
    super(B, self).__init__()

class C(B):
  def __init__(self):
    super(C, self).__init__()

b = B()
c = C()
print( b.name )
print( c.name )


>>>> B
>>>> C

Yeah, once you can get into python 3 you have the option of using argumentless super

class A(object):
  def __init__(self):
    self.name = type(self).__name__

class B(A):
  def __init__(self):
    super().__init__()

class C(B):
  def __init__(self):
    super().__init__()

One of the many little niceties that I miss when I have to go back and do py2 work.

2 Likes