有关记录的目的我想取回Python对象的完全限定类名。 (带完全合格我指的是类名包括包和模块名。)

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

有帮助吗?

解决方案

使用下面的程序

#! /usr/bin/env python

import foo

def fullname(o):
  # o.__module__ + "." + o.__class__.__qualname__ is an example in
  # this context of H.L. Mencken's "neat, plausible, and wrong."
  # Python makes no guarantees as to whether the __module__ special
  # attribute is defined, so we take a more circumspect approach.
  # Alas, the module name is explicitly excluded from __qualname__
  # in Python 3.

  module = o.__class__.__module__
  if module is None or module == str.__class__.__module__:
    return o.__class__.__name__  # Avoid reporting __builtin__
  else:
    return 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

其他提示

在提供的答案不处理嵌套类。虽然它不是可用,直到的Python 3.3( PEP 3155 ),你真的想用类的__qualname__。最终(3.4? PEP 395 ),__qualname__也将存在的模块来处理其中模块被重命名例(即当其被重命名为__main__)。

考虑使用具有类似功能inspect这可能是什么正在寻找getmodule模块:

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

下面是一个基于格雷格·培根的出色答卷,但有几个额外的检查:

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

__module__会做的伎俩。

尝试:

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

此网站表明__package__可能为Python 3.0工作;然而,鉴于那里的例子不会在我的Python 2.5.2控制台中工作。

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

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

'logging.handlers.MemoryHandler'

有些人(例如 https://stackoverflow.com/a/16763814/5766934 )主张__qualname__是更好比__name__。 下面是示出了差的示例:

$ cat dummy.py 
class One:
    class Two:
        pass

$ python3.6
>>> import dummy
>>> print(dummy.One)
<class 'dummy.One'>
>>> print(dummy.One.Two)
<class 'dummy.One.Two'>
>>> def full_name_with_name(klass):
...     return f'{klass.__module__}.{klass.__name__}'
>>> def full_name_with_qualname(klass):
...     return f'{klass.__module__}.{klass.__qualname__}'
>>> print(full_name_with_name(dummy.One))  # Correct
dummy.One
>>> print(full_name_with_name(dummy.One.Two))  # Wrong
dummy.Two
>>> print(full_name_with_qualname(dummy.One))  # Correct
dummy.One
>>> print(full_name_with_qualname(dummy.One.Two))  # Correct
dummy.One.Two

请注意,它也可以正确处理buildins:

>>> print(full_name_with_qualname(print))
builtins.print
>>> import builtins
>>> builtins.print
<built-in function print>

有关python3.7我使用:

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

获得:

package.subpackage.ClassName

由于这个话题的兴趣是获得完全合格的名称,这里是用相对进口与现有的在同一个包主模块一起时出现的陷阱。例如,与以下模块设置:

$ 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

下面是示出不同的导入相同的模块的结果的输出:

$ 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

当使用相对路径哼声进口棒,棒看到Baz.__module__为只是“baz”的,但在使用全名的第二进口,杆看到相同为“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
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top