170

ロギングの目的で、Pythonオブジェクトの完全修飾クラス名を取得したいと思います。(完全修飾とは、パッケージとモジュール名を含むクラス名を意味します。)

私は知ってx.__class__.__name__いますが、パッケージとモジュールを取得する簡単な方法はありますか?

4

12 に答える 12

184

次のプログラムで

#!/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

それでもPython2を使い続ける場合は、__name__の代わりにを使用する必要があります。__qualname__これは、ネストされたクラスの情報量が少なくなります。クラスにBarネストされたクラスは、次の代わりにFoo表示されます。BarFoo.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__
于 2010-01-07T12:03:02.580 に答える
51

提供された回答は、ネストされたクラスを扱いません。

Python 3.3(PEP 3155__qualname__ )以降、の代わりにクラスを使用できます__name__。そうでなければ、のようなクラス

class Foo:
    class Bar: # this one
        pass

Barの代わりにとして表示されFoo.Barます。

__module__(それでも、を個別にqualnameに付加する必要があります-__qualname__モジュール名を含めることを意図していません。)

于 2013-05-26T21:23:33.737 に答える
24

これはGregBaconの優れた回答に基づいていますが、いくつかの追加のチェックがあります。

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

于 2012-11-30T21:17:43.587 に答える
22

探しているもの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'>
于 2010-01-07T11:58:56.303 に答える
20

python3.7の場合、私は以下を使用します。

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

取得:

package.subpackage.ClassName
于 2019-05-21T10:28:40.113 に答える
10

__module__トリックを行います。

試す:

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

このサイト__package__は、 Python3.0で機能する可能性があることを示唆しています。ただし、そこに示されている例は、私のPython2.5.2コンソールでは機能しません。

于 2010-01-07T11:52:54.850 に答える
10

一部の人々(例えば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

ビルトインでも正しく機能することに注意してください。

>>> print(full_name_with_qualname(print))
builtins.print
>>> import builtins
>>> builtins.print
<built-in function print>
于 2018-05-22T10:23:49.470 に答える
7

これはハックですが、私は2.6をサポートしており、単純なものが必要です。

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

'logging.handlers.MemoryHandler'
于 2013-10-15T18:12:56.420 に答える
2

このトピックの関心は完全修飾名を取得することであるため、同じパッケージに存在するメインモジュールと一緒に相対インポートを使用するときに発生する落とし穴があります。たとえば、以下のモジュール設定で:

$ 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

humが相対パスを使用してbarをインポートする場合、barはBaz.__module__単に「baz」と見なされますが、フルネームを使用する2番目のインポートでは、barは「foo.baz」と同じように表示されます。

完全修飾名をどこかに永続化する場合は、それらのクラスの相対的なインポートを避けることをお勧めします。

于 2010-04-01T23:50:14.437 に答える
1

これは、修飾されたクラス名を使用するためのGregBaconMBによる回答の適応です。質問は修飾されたクラス名を求めていたことに注意してください。Python3.8でテストされました。

def fullname(obj: object) -> str:
    """Return the full name of the given object using its module and qualified class names."""
    # Ref: https://stackoverflow.com/a/66508248/
    module_name, class_name = obj.__class__.__module__, obj.__class__.__qualname__
    if module_name in (None, str.__class__.__module__):
        return class_name
    return module_name + "." + class_name

于 2021-03-06T16:55:31.197 に答える
1

Bellowは、Greg Baconの答えを改良したものであり、組み込みとユーザー定義の両方のクラス、インスタンス、メソッド、関数についてテストされています。

def fullname(o):
    try:
        # if o is a class or function, get module directly
        module = o.__module__
    except AttributeError:
        # then get module from o's class
        module = o.__class__.__module__
    try:
        # if o is a class or function, get name directly
        name = o.__qualname__
    except AttributeError:
        # then get o's class name
        name = o.__class__.__qualname__
    # if o is a method of builtin class, then module will be None
    if module == 'builtins' or module is None:
        return name
    return module + '.' + name
于 2022-01-13T08:00:24.927 に答える
0

ここでの答えはどれも私にはうまくいきませんでした。私の場合、Python 2.7を使用していて、新しいスタイルobjectのクラスでのみ作業することを知っていました。

def get_qualified_python_name_from_class(model):
    c = model.__class__.__mro__[0]
    name = c.__module__ + "." + c.__name__
    return name
于 2017-02-24T19:32:10.917 に答える