获取Python中对象的完全限定类名
为了记录日志,我想获取一个Python对象的完整类名。(这里的完整类名是指包括包和模块名称的类名。)
我知道可以用 x.__class__.__name__
来获取类名,但有没有简单的方法可以获取包和模块的信息呢?
13 个回答
33
这里有一个基于Greg Bacon很棒的回答,但增加了一些额外的检查:
__module__
可能是 None
(根据文档说明),而且对于像 str
这样的类型,它的值可能是 __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__
)
59
提供的答案没有涉及到嵌套类。
从 Python 3.3 开始(具体可以参考PEP 3155),你可以使用类的 __qualname__
,而不是 __name__
。否则,像下面这样的类
class Foo:
class Bar: # this one
pass
只会显示为 Bar
,而不是 Foo.Bar
。
(你仍然需要单独将 __module__
附加到 qualname,因为 __qualname__
本身并不包含模块名。)
219
下面这个程序
#!/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))
还有 Bar
这个类是这样定义的
class Bar(object):
def __init__(self, v=42):
self.val = v
运行后会得到这样的输出
$ ./prog.py
foo.Bar
如果你还在用 Python 2,那你需要用 __name__
代替 __qualname__
,不过 __name__
对于嵌套类的信息就没那么详细了——比如一个类 Bar
嵌套在另一个类 Foo
里面,输出会显示为 Bar
,而不是 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__