オブジェクトの現在のすべてのプロパティと値を出力するための組み込み関数はありますか?


回答:


591

あなたは本当に2つの異なるものを混ぜ合わせています。

dir()vars()またはinspectモジュールを使用して、興味のあるものを取得します(__builtins__例として使用しています。代わりに任意のオブジェクトを使用できます)。

>>> l = dir(__builtins__)
>>> d = __builtins__.__dict__

その辞書を好きなように印刷してください:

>>> print l
['ArithmeticError', 'AssertionError', 'AttributeError',...

または

>>> from pprint import pprint
>>> pprint(l)
['ArithmeticError',
 'AssertionError',
 'AttributeError',
 'BaseException',
 'DeprecationWarning',
...

>>> pprint(d, indent=2)
{ 'ArithmeticError': <type 'exceptions.ArithmeticError'>,
  'AssertionError': <type 'exceptions.AssertionError'>,
  'AttributeError': <type 'exceptions.AttributeError'>,
...
  '_': [ 'ArithmeticError',
         'AssertionError',
         'AttributeError',
         'BaseException',
         'DeprecationWarning',
...

インタラクティブなデバッガーでは、きれいな印刷をコマンドとして使用することもできます。

(Pdb) pp vars()
{'__builtins__': {'ArithmeticError': <type 'exceptions.ArithmeticError'>,
                  'AssertionError': <type 'exceptions.AssertionError'>,
                  'AttributeError': <type 'exceptions.AttributeError'>,
                  'BaseException': <type 'exceptions.BaseException'>,
                  'BufferError': <type 'exceptions.BufferError'>,
                  ...
                  'zip': <built-in function zip>},
 '__file__': 'pass.py',
 '__name__': '__main__'}

28
驚いたことに、すべてのオブジェクトに__dict__メンバー(re.MatchObjectたとえば)があるとは限りませんが、組み込みdir()オブジェクトはすべてのオブジェクトに対して機能します。
2012年

print re.compile(r'slots').search('No slots here either.').__slots__
ホブ、2012年

3
私にとって新しいもの。THX。ドットは私の脳のモジュールパスパーサーをトリガーしました。ラテン語の「モジュール」も考慮されていません。
ホブ、2012年

4
inspect答えの中でモジュールについてもっと話してみませんか?これはprint_rまたはvar_dumpに最も近いものだと思います。
ハイファイカル

1
dir()では、によってリストされた属性の背後にある値にどのようにアクセスしますか?dir()名前のリストのみを返します。属性内vars()または__dict__属性内に存在するものはすべてではありません。
HelloGoodbye

981

vars()混合したいpprint()

from pprint import pprint
pprint(vars(your_object))

24
vars()単に__dict__その引数のを返すだけdir()で、__dir__メソッドがない場合のフォールバックでもあります。だからdir()私が言ったように、最初の場所で使用してください。

28
@hop:dir()あなたはすべてのあなたは、おそらくのような気にしない事に建て与えます__str____new__var()しません。
Timmmm

14
これは、__dict__属性を持たないセットやその他のオブジェクトでは失敗します。
anatly techtonik 2015

209
def dump(obj):
  for attr in dir(obj):
    print("obj.%s = %r" % (attr, getattr(obj, attr)))

例外処理、国別/特殊文字の印刷、ネストされたオブジェクトへの再帰など、作者の好みに応じて追加するサードパーティの関数は数多くあります。しかし、それらはすべて基本的にこれに要約されます。


5
unpythonic、それはnot-invented-hereに従うため

14
何だって?確かgetmembers()に、標準inspectモジュールで関数を使用できますが、これは一般的にイントロスペクションを行う方法を示すという点で、より便利だと思いました。
Dan Lenski

20
どういたしまして。で見出されないDIR(OBJ)に示すような特性__dict__(例えば、__doc____module__)。さらに、で__dict__宣言されたオブジェクトに対してはまったく機能しません__slots__。一般に、__dict__実際にディクショナリに内部的に格納されているユーザーレベルのプロパティを示します。dir()はさらに表示します。
Dan Lenski

8
一部のクラス/オブジェクトには、__dict__属性/メンバーが含まれていません。私はそれがクレイジーだと知っていますが、本当です。intand strre.MatchObjects などの組み込みが一般的な例です。試してみて'hello'.__dict__、試してみてくださいdir('hello')
ホブ2012年

11
それが«unpythonic»かどうかは関係ありません。それは仕事を成し遂げ、それはデバッグにおいて重要な唯一のことです。
hidefromkgb 2018年

59

dirについては言及しましたが、属性の名前しか得られません。それらの値も必要な場合は、__ dict__を試してください。

class O:
   def __init__ (self):
      self.value = 3

o = O()

出力は次のとおりです。

>>> o.__dict__

{'value': 3}

9
以下のようなオブジェクトはsetありません__dict__ので、彼らのためにそれがで失敗しますAttributeError: 'set' object has no attribute '__dict__'
アナトリーtechtonik

23

これを行うには、「dir()」関数を使用できます。

>>> import sys
>>> dir(sys)
['__displayhook__', '__doc__', '__excepthook__', '__name__', '__stderr__', '__stdin__', '__stdo
t__', '_current_frames', '_getframe', 'api_version', 'argv', 'builtin_module_names', 'byteorder
, 'call_tracing', 'callstats', 'copyright', 'displayhook', 'dllhandle', 'exc_clear', 'exc_info'
 'exc_type', 'excepthook', 'exec_prefix', 'executable', 'exit', 'getcheckinterval', 'getdefault
ncoding', 'getfilesystemencoding', 'getrecursionlimit', 'getrefcount', 'getwindowsversion', 'he
version', 'maxint', 'maxunicode', 'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_
ache', 'platform', 'prefix', 'ps1', 'ps2', 'setcheckinterval', 'setprofile', 'setrecursionlimit
, 'settrace', 'stderr', 'stdin', 'stdout', 'subversion', 'version', 'version_info', 'warnoption
', 'winver']
>>>

別の便利な機能はヘルプです。

>>> help(sys)
Help on built-in module sys:

NAME
    sys

FILE
    (built-in)

MODULE DOCS
    http://www.python.org/doc/current/lib/module-sys.html

DESCRIPTION
    This module provides access to some objects used or maintained by the
    interpreter and to functions that interact strongly with the interpreter.

    Dynamic objects:

    argv -- command line arguments; argv[0] is the script pathname if known

22

オブジェクトの現在の状態を出力するには、次のようにします。

>>> obj # in an interpreter

または

print repr(obj) # in a script

または

print obj

クラスの定義__str__または__repr__メソッド。Pythonのドキュメントから:

__repr__(self)repr()組み込み関数と文字列変換(逆引用符)によって呼び出され、オブジェクトの「公式の」文字列表現を計算します。可能であれば、これは、同じ値を持つオブジェクトを再作成するために使用できる有効なPython式のように見えるはずです(適切な環境が与えられた場合)。これが不可能な場合は、「<... some役に立つ説明...>」という形式の文字列が返されます。戻り値は文字列オブジェクトでなければなりません。クラス定義は次の場合とrepr()ではなく__str__()、次に__repr__()そのクラスのインスタンスの「非公式」の文字列表現が要求される場合にも使用されます。これは通常、デバッグに使用されるため、表現が情報豊富で明確であることは重要です。

__str__(self)str()組み込み関数とprintステートメントによって呼び出され、オブジェクトの「非公式」文字列表現を計算します。これは__repr__()、有効なPython式である必要がないという点で異なります。代わりに、より便利で簡潔な表現を使用できます。戻り値は文字列オブジェクトでなければなりません。


このオプションは、オブジェクトの内容を連結した文字列を印刷するために有用である:print "DEBUG: object value: " + repr(obj)
AlejandroVD

17

チェックアウトする価値があるかもしれません-

PerlのData :: Dumperに相当するPythonはありますか?

私の推薦はこれです-

https://gist.github.com/1071857

perlには、オブジェクトデータをperlソースコードに変換するData :: Dumperというモジュールがあることに注意してください(注:コードをソースに変換しないため、ほとんどの場合、出力でオブジェクトメソッド関数を使用しません)。これは永続化に使用できますが、一般的な目的はデバッグです。

標準のpython pprintが達成できないことがいくつかあります。特に、オブジェクトのインスタンスを検出すると下降を停止し、オブジェクトの内部16進ポインターを提供します(エラー、そのポインターは、道)。つまり、Pythonはこの優れたオブジェクト指向のパラダイムのすべてですが、箱から出したツールは、オブジェクト以外のものを操作するために設計されています。

perl Data :: Dumperを使用すると、移動する深さを制御でき、循環リンク構造も検出できます(これは非常に重要です)。オブジェクトには祝福以外の特別な魔法がないため、このプロセスはperlで根本的に簡単に実現できます(広く定義されたプロセス)。


これは要点だけでなく、ピップとデブでなければなりません!
phobie 2015

2
>つまり、Pythonはすべてこの優れたオブジェクト指向のパラダイムについてですが、箱から出して得られるツールはオブジェクト以外のものを操作するために設計されています...提供している唯一の例が二次的に重要なモジュール。
memeplex 2016年

@memeplex pythonはすべて OOP に関するものですか?
ピーターウッド

OK、それはこの素晴らしい OOPがすべてだと言っているだけです。
memeplex 2018年

13

の使用をお勧めしhelp(your_object)ます。

help(dir)

 If called without an argument, return the names in the current scope.
 Else, return an alphabetized list of names comprising (some of) the attributes
 of the given object, and of attributes reachable from it.
 If the object supplies a method named __dir__, it will be used; otherwise
 the default dir() logic is used and returns:
 for a module object: the module's attributes.
 for a class object:  its attributes, and recursively the attributes
 of its bases.
 for any other object: its attributes, its class's attributes, and
 recursively the attributes of its class's base classes.

help(vars)

Without arguments, equivalent to locals().
With an argument, equivalent to object.__dict__.

おお、男、+ 100500
カービィ

12

ほとんどの場合、__dict__またはdir()を使用すると、必要な情報が得られます。さらに詳細が必要になった場合は、標準ライブラリにinspectモジュールが含まれています。これにより、印象的な詳細を取得できます。情報の実際の注意点には、次のものが含まれます。

  • 関数とメソッドのパラメーターの名前
  • クラス階層
  • 関数/クラスオブジェクトの実装のソースコード
  • フレームオブジェクト外のローカル変数

あなただけを探しているなら、「私のオブジェクトがどのような属性値を持っているのか?」、そして、dir()そして__dict__おそらく十分です。あなたが本当に任意のオブジェクトの現在の状態を掘り下げようとしているなら(Pythonではほとんどすべてがオブジェクトであることを覚えておいてください)、inspect検討する価値があります。


検査に関する説明を使用して、最も完全な回答を改善しました。よろしくお願いします。
フェルナンドセザール

9

オブジェクトの現在のすべてのプロパティと値を出力するための組み込み関数はありますか?

いいえ。最も賛成された回答は、いくつかの種類の属性を除外し、受け入れられた回答は、メソッドと非公開APIの一部を含むすべての属性を取得する方法を示しています。しかし、良い完全な組み込みはありません関数。

したがって、短い結果として、独自に記述できますが、パブリックAPIの一部であるプロパティおよびその他の計算されたデータ記述子が計算されます。

from pprint import pprint
from inspect import getmembers
from types import FunctionType

def attributes(obj):
    disallowed_names = {
      name for name, value in getmembers(type(obj)) 
        if isinstance(value, FunctionType)}
    return {
      name: getattr(obj, name) for name in dir(obj) 
        if name[0] != '_' and name not in disallowed_names and hasattr(obj, name)}

def print_attributes(obj):
    pprint(attributes(obj))

他の回答の問題

多くの異なる種類のデータメンバーを持つクラスで、現在上位投票されている回答の適用を観察します。

from pprint import pprint

class Obj:
    __slots__ = 'foo', 'bar', '__dict__'
    def __init__(self, baz):
        self.foo = ''
        self.bar = 0
        self.baz = baz
    @property
    def quux(self):
        return self.foo * self.bar

obj = Obj('baz')
pprint(vars(obj))

プリントのみ:

{'baz': 'baz'}

のでvars のみが返され__dict__たオブジェクトの、そしてそれはあなたがVARSによって返された辞書を変更している場合は、コピーではないのです、あなたも修正している__dict__オブジェクト自体のを。

vars(obj)['quux'] = 'WHAT?!'
vars(obj)

戻り値:

{'baz': 'baz', 'quux': 'WHAT?!'}

-これは悪いことです。quuxは、設定してはならないプロパティであり、名前空間に含めるべきではないからです...

現在受け入れられている回答(および他の回答)にアドバイスを適用することは、あまり良くありません。

>>> dir(obj)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', 'bar', 'baz', 'foo', 'quux']

ご覧のとおり、オブジェクトに関連付けられている名前のすべて(実際にはほとんど)dirのみを返します。

inspect.getmembersコメントに記載されている、同様に欠陥があります-すべての名前返し値をます。

クラスから

教えるときに、生徒にオブジェクトの意味論的にパブリックなAPIを提供する関数を作成させます。

def api(obj):
    return [name for name in dir(obj) if name[0] != '_']

これを拡張してオブジェクトのセマンティック名前空間のコピーを提供できますが、__slots__割り当てられていないものを除外する必要があり、「現在のプロパティ」のリクエストを真剣に受けている場合は、計算されたプロパティを除外する必要があります(それらは高価になる可能性があり、「最新」ではないと解釈される可能性があります):

from types import FunctionType
from inspect import getmembers

def attrs(obj):
     disallowed_properties = {
       name for name, value in getmembers(type(obj)) 
         if isinstance(value, (property, FunctionType))}
     return {
       name: getattr(obj, name) for name in api(obj) 
         if name not in disallowed_properties and hasattr(obj, name)}

そして今、私たちはプロパティquuxを計算したり表示したりしません:

>>> attrs(obj)
{'bar': 0, 'baz': 'baz', 'foo': ''}

注意事項

しかし、おそらく私達は私達の特性が高価ではないことを知っています。それらを含めるためにロジックを変更することもできます。また、他の カスタムデータ記述子を除外したい場合もあります。

次に、この関数をさらにカスタマイズする必要があります。そのため、必要な機能を魔法のように正確に認識し、それを提供する組み込み関数を使用することはできません。これは、私たちが自分で作成する必要がある機能です。

結論

これを行う組み込み関数はありません。状況に最も意味的に適切なことを行う必要があります。


の後に余分な閉じ括弧がありFunctionTypeます。しかし、とても役に立ちました-ありがとう!
nealmcb

@nealmcbありがとうございます。お役に立てて嬉しいです!:)
アーロンホール

7

マジックを使ったメタプログラミングの例Dumpオブジェクト

$猫dump.py
#!/usr/bin/python
import sys
if len(sys.argv) > 2:
    module, metaklass  = sys.argv[1:3]
    m = __import__(module, globals(), locals(), [metaklass])
    __metaclass__ = getattr(m, metaklass)

class Data:
    def __init__(self):
        self.num = 38
        self.lst = ['a','b','c']
        self.str = 'spam'
    dumps   = lambda self: repr(self)
    __str__ = lambda self: self.dumps()

data = Data()
print data

引数なし:

$ python dump.py
<__main__.Data instance at 0x00A052D8>

グノーシスUtilsの

$ python dump.py gnosis.magic MetaXMLPickler
<?xml version="1.0"?>
<!DOCTYPE PyObject SYSTEM "PyObjects.dtd">
<PyObject module="__main__" class="Data" id="11038416">
<attr name="lst" type="list" id="11196136" >
  <item type="string" value="a" />
  <item type="string" value="b" />
  <item type="string" value="c" />
</attr>
<attr name="num" type="numeric" value="38" />
<attr name="str" type="string" value="spam" />
</PyObject>

少し時代遅れですが、まだ機能しています。


6

これをデバッグに使用していて、すべてを再帰的にダンプしたい場合は、クラスに__str__すでに適切な実装が必要であるため、受け入れられた答えは満足できません。そうでない場合、これははるかにうまく機能します。

import json
print(json.dumps(YOUR_OBJECT, 
                 default=lambda obj: vars(obj),
                 indent=1))

これはpython 3では機能しませんでした。pymongoをインストールし、@ Clarkの回答に従ってそれを実行しなければなりませんでした
Tim Ogilvy

ここに他の多くの回答と同様にTypeError: vars() argument must have __dict__ attribute
ロブ

6

トライppretty

from ppretty import ppretty


class A(object):
    s = 5

    def __init__(self):
        self._p = 8

    @property
    def foo(self):
        return range(10)


print ppretty(A(), show_protected=True, show_static=True, show_properties=True)

出力:

__main__.A(_p = 8, foo = [0, 1, ..., 8, 9], s = 5)

正確なデバッグのために私が探していたもの:)、素晴らしい発見!
ジョセフアストラハン

少しのヒントとして、depth = 6(または必要な限り)を追加します。これは、そのパラメーターの1つであり、再帰の詳細がさらに進む可能性があります。それはリストを出力する方法についての事私のようなの一つは、あなたはそれが働いている知っているので、それは最初の2つのentiresと最後の2つの項目を示している
ジョセフAstrahan

4
from pprint import pprint

def print_r(the_object):
    print ("CLASS: ", the_object.__class__.__name__, " (BASE CLASS: ", the_object.__class__.__bases__,")")
    pprint(vars(the_object))

4

これにより、すべてのオブジェクトの内容がjsonまたはyamlのインデント形式で再帰的に出力されます。

import jsonpickle # pip install jsonpickle
import json
import yaml # pip install pyyaml

serialized = jsonpickle.encode(obj, max_depth=2) # max_depth is optional
print json.dumps(json.loads(serialized), indent=4)
print yaml.dump(yaml.load(serialized), indent=4)

4

私はpprintのみに言及している回答に賛成しました。明確にするために、複雑なデータ構造のすべてのを表示したい場合は、次のようにします。

from pprint import pprint
pprint(my_var)

ここで、my_varは目的の変数です。私が使用したときpprint(vars(my_var))、私は何も得ず、ここでの他の答えが役に立たなかったか、メソッドが不必要に長く見えました。ちなみに、私の特定のケースでは、調べていたコードに辞書の辞書がありました。

いくつかのカスタムクラスでは、役に立たない<someobject.ExampleClass object at 0x7f739267f400>種類の出力になってしまう可能性があることを指摘する価値があります。その場合は、__str__メソッドを実装するか、他のソリューションのいくつかを試す必要があります。サードパーティのライブラリがなくても、すべてのシナリオで機能するシンプルなものを見つけたいと思っています。


3
>いくつかのカスタムクラスを使って...これが私がPythonのファンではない理由です。「時々」機能するものと「時々」機能しないもの
AlxVallejo

3

一部のログにデバッグ情報を出力する必要があり、pprintが壊れてしまうため使用できませんでした。代わりに私はこれを行い、事実上同じものを得ました。

DO = DemoObject()

itemDir = DO.__dict__

for i in itemDir:
    print '{0}  :  {1}'.format(i, itemDir[i])

3

「myObject」をダンプするには:

from bson import json_util
import json

print(json.dumps(myObject, default=json_util.default, sort_keys=True, indent=4, separators=(',', ': ')))

私はvars()とdir();を試しました。どちらも私が探していたものに失敗しました。オブジェクトに__dict__がなかったため、vars()は機能しませんでした(exceptions.TypeError:vars()引数には__dict__属性が必要です)。dir()は私が探していたものではありませんでした。これは単なるフィールド名のリストであり、値やオブジェクト構造を提供しません。

私はjson.dumps()がdefault = json_util.defaultなしでほとんどのオブジェクトで機能すると思いますが、オブジェクトに日時フィールドがあったため、標準のjsonシリアライザーが失敗しました。Pythonで「datetime.datetimeがJSONシリアル化可能ではない」を克服する方法を参照してください


さて、それを使用するにはpymongo thoをインストールする必要がありました。
Tim Ogilvy

3

なぜ単純ではないのですか?

for key,value in obj.__dict__.iteritems():
    print key,value

そうじゃないのfor key,value in obj.__dict__.iteritems(): print key,value
Raz

2

pprintには、データ構造の美的に満足のいく表現を生成するための「きれいなプリンター」が含まれています。フォーマッタは、インタプリタで正しく解析できるデータ構造の表現を生成します。また、人間が読むのも簡単です。可能であれば、出力は単一行に保持され、複数行に分割されるとインデントされます。


2

beeprintを試してください

オブジェクト変数の印刷だけでなく、次のような美しい出力も役立ちます。

class(NormalClassNewStyle):
  dicts: {
  },
  lists: [],
  static_props: 1,
  tupl: (1, 2)

1
このモジュールはもうメンテナンスされていないようで、いくつかの未解決の問題があります。むしろpprettyを
Wavesailor

1

苦労しているすべての人のために

  • vars() すべての属性を返さない。
  • dir() 属性の値を返しません。

次のコードは、すべての属性objとその値を出力します。

for attr in dir(obj):
        try:
            print("obj.{} = {}".format(attr, getattr(obj, attr)))
        except AttributeError:
            print("obj.{} = ?".format(attr))

エラーは発生しませんが、再帰的ではないため、16進数のアドレスをたくさん取得してください
rob

0

Flaskデバッグツールバーを試すことができます。
https://pypi.python.org/pypi/Flask-DebugToolbar

from flask import Flask
from flask_debugtoolbar import DebugToolbarExtension

app = Flask(__name__)

# the toolbar is only enabled in debug mode:
app.debug = True

# set a 'SECRET_KEY' to enable the Flask session cookies
app.config['SECRET_KEY'] = '<replace with a secret key>'

toolbar = DebugToolbarExtension(app)


0

これは、変数がクラス内、__ init__の内部または外部でどのように定義されていても機能します。

your_obj = YourObj()
attrs_with_value = {attr: getattr(your_obj, attr) for attr in dir(your_obj)}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.