在Python中获取对象的全限定名称

为了logging目的,我想检索一个Python对象的全限定类名。 (完全合格的我的意思是类名,包括包和模块名称。)

我知道x.__class__.__name__ ,但有一个简单的方法来获取包和模块?

用下面的程序

 #! /usr/bin/env python import foo def fullname(o): return o.__module__ + "." + o.__class__.__name__ bar = foo.Bar() print fullname(bar) 

Bar定义为

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

输出是

 $ ./prog.py foo.Bar 

考虑使用具有getmodulefunction的inspect模块,它可能是寻找的东西:

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

提供的答案不处理嵌套的类。 虽然在Python 3.3( PEP 3155 )之前它不可用,但是你真的想使用类的__qualname__ 。 最后(3.4? PEP 395 ), __qualname__也会存在,用于处理模块重命名(即重命名为__main__ )的情况。

这里有一个基于Greg Bacon的出色答案,但是还有一些额外的检查:

__module__可以是None (根据文档),也可以是像str这样的types,它可以是__builtin__ (你可能不希望出现在日志或其他)。 以下检查这两种可能性:

 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__ 

(有可能是一个更好的方法来检查__builtin__上面只是依赖于str总是可用的事实,它的模块总是__builtin__

__module__会做的伎俩。

尝试:

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

这个网站build议__package__可能适用于Python 3.0; 但是,这里给出的例子在我的Python 2.5.2控制台下不起作用。

这是一个黑客,但我支持2.6,只需要一些简单的:

 >>> from logging.handlers import MemoryHandler as MH >>> str(MH).split("'")[1] 'logging.handlers.MemoryHandler' 

由于本主题的兴趣是获取完全限定名称,因此在使用相对导入function以及相同包中的主模块时,会出现一个错误。 例如:

 $ 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 

当嗡嗡声使用相对path导入栏时,bar将Baz.__module__看作是“baz”,但在使用全名的第二个导入中,bar看起来与“foo.baz”相同。

如果您要在某处保留完全限定的名称,最好避免这些类的相对导入。

这里没有答案为我工作。 在我的情况下,我使用Python 2.7,知道我只会使用newstyle object类。

 def get_qualified_python_name_from_class(model): c = model.__class__.__mro__[0] name = c.__module__ + "." + c.__name__ return name