Get fully qualified class name of an object in Python

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__

The provided answers don't deal with nested classes. Though it's not available until Python 3.3 (PEP 3155), you really want to use the __qualname__ of the class instead of the __name__. Otherwise, a class like

class Foo:
    class Bar: # this one
        pass

will show up as just Bar instead of Foo.Bar.

(You'll still need to attach the __module__ to the qualname separately - __qualname__ is not intended to include module names.)


Here's one based on Greg Bacon's excellent answer, but with a couple of extra checks:

__module__ can be None (according to the docs), and also for a type like str it can be __builtin__ (which you might not want appearing in logs or whatever). The following checks for both those possibilities:

def fullname(o):
    module = o.__class__.__module__
    if module is None or module == str.__class__.__module__:
        return o.__class__.__name__
    return module + '.' + o.__class__.__name__

(There might be a better way to check for __builtin__. The above just relies on the fact that str is always available, and its module is always __builtin__)


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'>