Get fully qualified class name of an object in Python

Viewed 118432

For logging purposes I want to retrieve the fully qualified class name of a Python object. (With fully qualified I mean the class name including the package and module name.)

I know about x.__class__.__name__, but is there a simple method to get the package and module?

12 Answers

With the following program

#!/usr/bin/env python

import foo

def fullname(o):
    klass = o.__class__
    module = klass.__module__
    if module == 'builtins':
        return klass.__qualname__ # avoid outputs like 'builtins.str'
    return module + '.' + klass.__qualname__

bar = foo.Bar()
print(fullname(bar))

and Bar defined as

class Bar(object):
  def __init__(self, v=42):
    self.val = v

the output is

$ ./prog.py
foo.Bar

If you're still stuck on Python 2, you'll have to use __name__ instead of __qualname__, which is less informative for nested classes - a class Bar nested in a class Foo will show up as Bar instead of Foo.Bar:

def fullname(o):
    klass = o.__class__
    module = klass.__module__
    if module == '__builtin__':
        return klass.__name__ # avoid outputs like '__builtin__.str'
    return module + '.' + klass.__name__

Consider using the inspect module which has functions like getmodule which might be what are looking for:

>>>import inspect
>>>import xml.etree.ElementTree
>>>et = xml.etree.ElementTree.ElementTree()
>>>inspect.getmodule(et)
<module 'xml.etree.ElementTree' from 
        'D:\tools\python2.5.2\lib\xml\etree\ElementTree.pyc'>

For python3.7 I use:

".".join([obj.__module__, obj.__name__])

Getting:

package.subpackage.ClassName

__module__ would do the trick.

Try:

>>> import re
>>> print re.compile.__module__
re

This site suggests that __package__ might work for Python 3.0; However, the examples given there won't work under my Python 2.5.2 console.

Some people (e.g. https://stackoverflow.com/a/16763814/5766934) arguing that __qualname__ is better than __name__. Here is an example that shows the difference:

$ cat dummy.py 
class One:
    class Two:
        pass

$ python3.6
>>> import dummy
>>> print(dummy.One)
<class 'dummy.One'>
>>> print(dummy.One.Two)
<class 'dummy.One.Two'>
>>> def full_name_with_name(klass):
...     return f'{klass.__module__}.{klass.__name__}'
>>> def full_name_with_qualname(klass):
...     return f'{klass.__module__}.{klass.__qualname__}'
>>> print(full_name_with_name(dummy.One))  # Correct
dummy.One
>>> print(full_name_with_name(dummy.One.Two))  # Wrong
dummy.Two
>>> print(full_name_with_qualname(dummy.One))  # Correct
dummy.One
>>> print(full_name_with_qualname(dummy.One.Two))  # Correct
dummy.One.Two

Note, it also works correctly for builtins:

>>> print(full_name_with_qualname(print))
builtins.print
>>> import builtins
>>> builtins.print
<built-in function print>

This is an adaption of the answers by Greg Bacon and MB to use the qualified class name. Note that the question did ask for the qualified class name. It was tested with Python 3.8.

def fullname(obj: object) -> str:
    """Return the full name of the given object using its module and qualified class names."""
    # Ref: https://stackoverflow.com/a/66508248/
    module_name, class_name = obj.__class__.__module__, obj.__class__.__qualname__
    if module_name in (None, str.__class__.__module__):
        return class_name
    return module_name + "." + class_name

Bellow is just an improvement of Greg Bacon's answer, tested for class, instance, method, function, both builtin and user defined.

def fullname(o):
    try:
        # if o is a class or function, get module directly
        module = o.__module__
    except AttributeError:
        # then get module from o's class
        module = o.__class__.__module__
    try:
        # if o is a class or function, get name directly
        name = o.__qualname__
    except AttributeError:
        # then get o's class name
        name = o.__class__.__qualname__
    # if o is a method of builtin class, then module will be None
    if module == 'builtins' or module is None:
        return name
    return module + '.' + name
Related