views:

369

answers:

4

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?

+2  A: 

__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.

Adam Matan
That does the trick, thanks!For the fully qualified name I will use`"%s.%s" % (x.__class__.__module__, x.__class__.__name__)`
Hanno Stock
+4  A: 

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'>
Tendayi Mawushe
+5  A: 

With the following program

#! /usr/bin/env python

import foo

def fullname(o):
  return o.__module__ + "." + o.__class__.__name__

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
Greg Bacon
+1 Nice one! Why don't you add `__package__` ?
Adam Matan
A: 

Since the interest of this topic is to get fully qualified names, here is a pitfall that occurs when using relative imports along with the main module existing in the same package. E.g.:

$ mkdir -p /tmp/fqname/foo
$ touch /tmp/fqname/foo/__init__.py
$ cat<<END > /tmp/fqname/foo/bar.py
> from baz import Baz
> print Baz.__module__
> END
$ cat<<END > /tmp/fqname/foo/baz.py
> class Baz: pass
> END
$ cat <<END > /tmp/fqname/main.py
> import foo.bar
> from foo.baz import Baz
> print Baz.__module__
> END
$ cat <<END > /tmp/fqname/foo/hum.py
> import bar
> import foo.bar
> END
$ PYTHONPATH=/tmp/fqname python /tmp/fqname/main.py
foo.baz
foo.baz
$ PYTHONPATH=/tmp/fqname python /tmp/fqname/foo/bar.py
baz
$ PYTHONPATH=/tmp/fqname python /tmp/fqname/foo/hum.py
baz
foo.baz

When hum imports bar using relative path, bar sees Baz.__module__ as just "baz", but in the second import that uses full name, bar sees the same as "foo.baz".

If you are persisting the fully-qualified names somewhere, it is better to avoid relative imports for those classes.

haridsv