質問

ログ記録の目的のために私は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

。しかし、そこに与えられた例は私の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__見ているが、完全な名前を使用する第2のインポートでは、バーは「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