125

How do I get the name of the class I am currently in?

Example:

def get_input(class_name):
    [do things]
    return class_name_result

class foo():
    input = get_input([class name goes here])

Due to the nature of the program I am interfacing with (vistrails), I cannot use __init__() to initialize input.

martineau
  • 119,623
  • 25
  • 170
  • 301
Jonathan Ginsburg
  • 1,259
  • 2
  • 9
  • 5

9 Answers9

192

obj.__class__.__name__ will get you any objects name, so you can do this:

class Clazz():
    def getName(self):
        return self.__class__.__name__

Usage:

>>> c = Clazz()
>>> c.getName()
'Clazz'
Yuval Adam
  • 161,610
  • 92
  • 305
  • 395
  • 1
    Why isn't this the accepted answer? EDIT: Ok OP's scope isn't inner, it's at class level. – KomodoDave Nov 10 '14 at 12:51
  • 8
    @KomodoDave, because this is wrong, even in the method scope. When you call `getName` from a child class it will output the child class name. It then gets tricky if you REALLy want the class you're working with. – Yukio Usuzumi Jun 08 '15 at 05:16
  • @KenetJervet You mean when you call `getName` from a _parent_ class it will output the child class name? Ok ty for pointing that out. – KomodoDave Jun 08 '15 at 08:06
  • 8
    In OO-terms, the solution (returning the actual runtime child class name even if the `getName()` method happens to be defined in a superclass) is correct though. – sxc731 Oct 15 '16 at 18:57
26

PEP 3155 introduced __qualname__, which was implemented in Python 3.3.

For top-level functions and classes, the __qualname__ attribute is equal to the __name__ attribute. For nested classes, methods, and nested functions, the __qualname__ attribute contains a dotted path leading to the object from the module top-level.

It is accessible from within the very definition of a class or a function, so for instance:

class Foo:
    print(__qualname__)

will effectively print Foo. You'll get the fully qualified name (excluding the module's name), so you might want to split it on the . character.

However, there is no way to get an actual handle on the class being defined.

>>> class Foo:
...     print('Foo' in globals())
... 
False
Right leg
  • 16,080
  • 7
  • 48
  • 81
24

Within the body of a class, the class name isn't defined yet, so it is not available. Can you not simply type the name of the class? Maybe you need to say more about the problem so we can find a solution for you.

I would create a metaclass to do this work for you. It's invoked at class creation time (conceptually at the very end of the class: block), and can manipulate the class being created. I haven't tested this:

class InputAssigningMetaclass(type):
    def __new__(cls, name, bases, attrs):
        cls.input = get_input(name)
        return super(MyType, cls).__new__(cls, name, bases, newattrs)

class MyBaseFoo(object):
    __metaclass__ = InputAssigningMetaclass

class foo(MyBaseFoo):
    # etc, no need to create 'input'

class foo2(MyBaseFoo):
    # etc, no need to create 'input'
Ned Batchelder
  • 364,293
  • 75
  • 561
  • 662
  • TO clarify what I am trying to do: I need to create and initialize a class variable, 'input', **outside of a method**. I have a bunch of small classes, each which must call 'get_input' using their class name as the parameter. I am trying to generalize this so I don't have to go to each class (there will be 100 or so) and type in the name of class. – Jonathan Ginsburg Aug 04 '11 at 14:46
  • OK, I've updated my answer with a metaclass that should help. – Ned Batchelder Aug 04 '11 at 14:54
  • 2
    What does `MyType` in the `super` line in `InputAssigningMetaclass` refer to? – A.Wan Dec 01 '15 at 22:58
22

You can access it by the class' private attributes:

cls_name = self.__class__.__name__

EDIT:

As said by Ned Batchelder, this wouldn't work in the class body, but it would in a method.

Joe
  • 6,758
  • 2
  • 26
  • 47
mdeous
  • 17,513
  • 7
  • 56
  • 60
  • How reference the class in the class body? I need to pass the current class to another class. – Savvy Aug 15 '21 at 18:39
7

EDIT: Yes, you can; but you have to cheat: The currently running class name is present on the call stack, and the traceback module allows you to access the stack.

>>> import traceback
>>> def get_input(class_name):
...     return class_name.encode('rot13')
... 
>>> class foo(object):
...      _name = traceback.extract_stack()[-1][2]
...     input = get_input(_name)
... 
>>> 
>>> foo.input
'sbb'

However, I wouldn't do this; My original answer is still my own preference as a solution. Original answer:

probably the very simplest solution is to use a decorator, which is similar to Ned's answer involving metaclasses, but less powerful (decorators are capable of black magic, but metaclasses are capable of ancient, occult black magic)

>>> def get_input(class_name):
...     return class_name.encode('rot13')
... 
>>> def inputize(cls):
...     cls.input = get_input(cls.__name__)
...     return cls
... 
>>> @inputize
... class foo(object):
...     pass
... 
>>> foo.input
'sbb'
>>> 
SingleNegationElimination
  • 151,563
  • 33
  • 264
  • 304
3

@Yuval Adam answer using @property

class Foo():
    @property
    def name(self):
        return self.__class__.__name__

f = Foo()
f.name  # will give 'Foo'

Anandhu Gopi
  • 61
  • 1
  • 4
2

I think, it should be like this:

    class foo():
        input = get_input(__qualname__)
Shtefan
  • 742
  • 12
  • 14
1
import sys

def class_meta(frame):
    class_context = '__module__' in frame.f_locals
    assert class_context, 'Frame is not a class context'

    module_name = frame.f_locals['__module__']
    class_name = frame.f_code.co_name
    return module_name, class_name

def print_class_path():
    print('%s.%s' % class_meta(sys._getframe(1)))

class MyClass(object):
    print_class_path()
Pavel Patrin
  • 1,630
  • 1
  • 19
  • 33
0

I'm using python3.8 and below is example to get your current class name.

class MyObject():
    @classmethod
    def print_class_name(self):
        print(self.__name__)

MyObject.print_class_name()

Or without @classmethod you can use

class ClassA():
    def sayhello(self):
        print(self.getName())
    
    def getName(self):
        return self.__class__.__name__

  ClassA().sayhello()

Hope that helps others !!!

Manish Jaiswal
  • 442
  • 5
  • 19