Get fully qualified class name of an object in Pyt

2020-01-24 04:30发布

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?

10条回答
地球回转人心会变
2楼-- · 2020-01-24 04:39

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'>
查看更多
相关推荐>>
3楼-- · 2020-01-24 04:43

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

查看更多
唯我独甜
4楼-- · 2020-01-24 04:47

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., with the below module setup:

$ cat /tmp/fqname/foo/__init__.py
$ cat /tmp/fqname/foo/bar.py
from baz import Baz
print Baz.__module__
$ cat /tmp/fqname/foo/baz.py
class Baz: pass
$ cat /tmp/fqname/main.py
import foo.bar
from foo.baz import Baz
print Baz.__module__
$ cat /tmp/fqname/foo/hum.py
import bar
import foo.bar

Here is the output showing the result of importing the same module differently:

$ export PYTHONPATH=/tmp/fqname
$ python /tmp/fqname/main.py
foo.baz
foo.baz
$ python /tmp/fqname/foo/bar.py
baz
$ 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.

查看更多
一纸荒年 Trace。
5楼-- · 2020-01-24 04:48

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

查看更多
你好瞎i
6楼-- · 2020-01-24 04:50

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 __qualname__ of the class. Eventually (3.4? PEP 395), __qualname__ will also exist for modules to deal with cases where the module is renamed (i.e. when it is renamed to __main__).

查看更多
【Aperson】
7楼-- · 2020-01-24 04:55

For python3.7 I use:

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

Getting:

package.subpackage.ClassName
查看更多
登录 后发表回答