Pythonオブジェクトの内部をどのように調べますか?


291

Pythonを使用したさまざまなプロジェクト(Django Web開発およびPanda3Dゲーム開発を含む)でコーディングを始めています。

何が起こっているのかを理解するのを助けるために、基本的にはPythonオブジェクトの内部を「見て」、それらがどのように動くかを確認したいと思います-メソッドやプロパティのように。

だから私はPythonオブジェクトを持っているとしましょう、その内容を印刷するには何が必要ですか?それは可能ですか?

回答:


352

Pythonには、強力なイントロスペクション機能があります。

次の組み込み関数を見てください。

type()そしてdir()、オブジェクトの種類と、それぞれの属性のセットを検査するために特に有用です。


25
その用語が「内省」であることを知りませんでした。それは大きな助けです!あなたが私に与えたすべての機能と同様に...ありがとう!
littlejim84 2009年

2
property、classmethod、staticmethodはイントロスペクションとは関係ありません。これらのメソッドはすべて、特別な動作を持つクラスを定義するために使用できる特別なタイプのオブジェクトを作成しますが、それらのクラスまたは構成を検査するのに役立ちません。
SingleNegationElimination 2009年

以下の@Brianからの回答は、Python内からさまざまなPythonオブジェクトのソースコードを表示する方法も示しています。それが私が最初に探していたものであり、私は一人になることはないと確信しています。(これが最も受け入れられているので、この回答に彼の回答への参照を含めることは価値があるかもしれません。)
michaelavila

Pythonの組み込みの「IntelliSense」のようなものです。大好きです。
Bruno Bieri 2016年

7
私はそれは悪い答えだと思います。ソリューションを提供する代わりに、ドキュメントに関連するすべてのものを提供するだけです
Ishan Srivastava '29

176

object.__dict__


12
vars(object)そのために作られました。
liberforce

6
実際from pprint import pprint; pprint(vars(object))に、オブジェクトの内容について本当に素晴らしい見解を与えてくれました。ありがとう@liberforce
N.

オブジェクトとその内容を文字列で表示するための最良の方法
Peter Krauss

これは、任意の表現メソッドを実装するオブジェクト、またはgoogleapiclient.errors.HttpErrorのようなオブジェクトを表示する優れた方法です。これらのオブジェクトを印刷すると、確実に不十分な情報が表示されます。@ mtasic85
Felipe Valdes

65

まず、ソースを読みます。

次に、dir()関数を使用します。


92
その順序を逆にします。
バイエル、2009年

5
ソースはdir()よりも有益であり、開発するためのより良い習慣です。
S.Lott、2009年

14
失礼ですが同意できません。dir()は非常に高速であり、99%のケースで、help()と組み合わせて必要なものを見つけましょう。
バイエル、2009年

7
私はいつも役に立たないことに同意します。多くの場合、dir()への単純な呼び出しで十分なので、ソースコードを調べる必要がなくなります。
サーシャチェディゴフ2009年

3
実行時にオブジェクトを検査することが役立つ場合がありますが、ソースを読み取ることは役立ちません。たとえば、httplib.pyクラスとそのメソッド:)。
Denis Barmenkov 2012

61

誰も言及したヘルプにまだ驚いています!

In [1]: def foo():
   ...:     "foo!"
   ...:

In [2]: help(foo)
Help on function foo in module __main__:

foo()
    foo!

ヘルプを使用すると、ドキュメント文字列を読んで、クラスがどのような属性を持っているかを知ることができます。これは非常に役立ちます。


次に、ここで説明した他の手法を使用します。しかし、docstringが利用可能な場合は、正規のものと考えてください。
エドワードフォーク

過去数年間にPythonがこの関数を更新したかどうかはわかりませんが、「help(object_name)」は高度に構造化された形式で完全な概要を提供します。それは番人です。ありがとう。
Brian Cugelman

27

これが何が起こっているのかを調べるための探索である場合は、IPythonを確認することをお勧めします。これにより、オブジェクトのドキュメント、プロパティ、さらにはソースコードを取得するためのさまざまなショートカットが追加されます。たとえば、「?」を追加します 関数にオブジェクトのヘルプ(実質的には「help(obj)」のショートカット)を提供します。2つの?( " func??")を使用すると、ソースコードが利用可能な場合に表示されます。

また、タブ補完、結果のきれいな印刷、結果履歴など、この種の探索的プログラミングに非常に便利な便利な機能もたくさんあります。

イントロスペクションの多くのプログラムで使用するため、などの基本的な組み込みコマンドdir()vars()getattrなどが有用であろうが、チェックアウトして、あなたの時間の価値が充分ある検査モジュールを。関数のソースを取得するには、 " inspect.getsource"を使用します。たとえば、それ自体に適用します。

>>> print inspect.getsource(inspect.getsource)
def getsource(object):
    """Return the text of the source code for an object.

    The argument may be a module, class, method, function, traceback, frame,
    or code object.  The source code is returned as a single string.  An
    IOError is raised if the source code cannot be retrieved."""
    lines, lnum = getsourcelines(object)
    return string.join(lines, '')

inspect.getargspec 関数パラメーターの名前とデフォルト値を提供するため、関数のラッピングや操作を行う場合にも頻繁に役立ちます。


18

このためのGUIに興味がある場合は、objbrowserを参照してください。下のオブジェクトイントロスペクションには、Python標準ライブラリのinspectモジュールを使用します。

objbrowserscreenshot


9

シェルでdir()を使用してオブジェクトの属性をリストできます。

>>> dir(object())
['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']

もちろん、inspectモジュールもあります:http : //docs.python.org/library/inspect.html#module-inspect


8
"""Visit http://diveintopython.net/"""

__author__ = "Mark Pilgrim (mark@diveintopython.org)"


def info(object, spacing=10, collapse=1):
    """Print methods and doc strings.

    Takes module, class, list, dictionary, or string."""
    methodList = [e for e in dir(object) if callable(getattr(object, e))]
    processFunc = collapse and (lambda s: " ".join(s.split())) or (lambda s: s)
    print "\n".join(["%s %s" %
                     (method.ljust(spacing),
                      processFunc(str(getattr(object, method).__doc__)))
                     for method in methodList])

if __name__ == "__main__":
    print help.__doc__

4
これは、プリントの周囲に括弧を追加するだけで、Python 3で正常に機能します。
ConstantineK

8

トライ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(), indent='    ', depth=2, width=30, seq_length=6,
              show_protected=True, show_private=False, show_static=True,
              show_properties=True, show_address=True)

出力:

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

7

他の人はすでにあなたが探しているように聞こえる組み込みのdir()について言及していますが、ここに別の良いヒントがあります。ほとんどの標準ライブラリを含む多くのライブラリは、ソース形式で配布されています。つまり、ソースコードを直接簡単に読み取ることができます。秘訣はそれを見つけることです。例えば:

>>> import string
>>> string.__file__
'/usr/lib/python2.5/string.pyc'

* .pycファイルはコンパイルされているので、末尾の「c」を削除して、コンパイルされていない* .pyファイルをお気に入りのエディターまたはファイルビューアーで開きます。

/usr/lib/python2.5/string.py

これは、特定のAPIからどの例外が発生するかなどを見つけるのに非常に役立つことがわかりました。この種の詳細は、Pythonの世界ではめったに文書化されていません。


7

一方でpprint他の人がすでに述べてきた私はいくつかのコンテキストを追加したいと思います。

pprintモジュールは、インタプリタへの入力として使用できる形式で任意のPythonデータ構造を「きれいに印刷」する機能を提供します。フォーマットされた構造に基本的なPythonタイプではないオブジェクトが含まれている場合、表現はロードできない可能性があります。これは、ファイル、ソケット、クラス、インスタンスなどのオブジェクト、およびPython定数として表現できない他の多くの組み込みオブジェクトが含まれている場合に当てはまります。

pprint に代わるものを探しているPHPのバックグラウンドを持つ開発者からの需要が高いかもしれません var_dump()

dict属性を持つオブジェクトは、モジュール、クラス、インスタンスなどの属性を返すpprint()との混合を使用して適切にダンプできます。vars()__dict__

from pprint import pprint
pprint(vars(your_object))

したがって、ループは必要ありません

グローバルスコープまたはローカルスコープに含まれるすべての変数をダンプするには、次のコマンドを使用します。

pprint(globals())
pprint(locals())

locals()関数で定義された変数を示します。他の使用法の
中で、対応する名前を文字列キーとして使用して関数にアクセスすると便利です。

locals()['foo']() # foo()
globals()['foo']() # foo()

同様に、dir()モジュールのコンテンツまたはオブジェクトの属性を表示するために使用します。

そして、まだまだあります。


4

パラメータやメソッドを見たい場合は、他の人が指摘しているようにpprintdir()

コンテンツの実際の値を見たい場合は、

object.__dict__


4

コードを検査するための2つの優れたツールは次のとおりです。

  1. IPython。タブ補完を使用して検査できるPython端末。

  2. EclipsePyDevプラグイン。優れたデバッガーを備えているため、特定の場所でブレークし、すべての変数をツリーとして参照してオブジェクトを検査できます。埋め込み端末を使用して、その場所でコードを試すか、オブジェクトを入力して「。」を押すこともできます。コードヒントを提供するため。

ここに画像の説明を入力してください




3

あなたがオブジェクトに対応する機能のソースコードを見て興味を持っている場合myobj、あなたはで入力することができますiPythonJupyter Notebook

myobj??


2
import pprint

pprint.pprint(obj.__dict__)

または

pprint.pprint(vars(obj))

このコードは質問に答えることがありますが、問題を解決する方法および/または理由に関する追加のコンテキストを提供すると、回答の長期的な価値が向上します。
Alexander

1

ライブオブジェクトの内部を見たい場合inspectは、Pythonのモジュールが適切な答えです。一般に、ディスク上のどこかにあるソースファイルで定義されている関数のソースコードを取得するために機能します。インタープリターで定義されたライブ関数とラムダのソースを取得する場合は、dill.source.getsourcefrom を使用できますdill。また、カレーで定義されたバインド済みまたはバインドなしのクラスメソッドおよび関数からコードを取得することもできます。ただし、囲んでいるオブジェクトのコードがないと、そのコードをコンパイルできない場合があります。

>>> from dill.source import getsource
>>> 
>>> def add(x,y):
...   return x+y
... 
>>> squared = lambda x:x**2
>>> 
>>> print getsource(add)
def add(x,y):
  return x+y

>>> print getsource(squared)
squared = lambda x:x**2

>>> 
>>> class Foo(object):
...   def bar(self, x):
...     return x*x+x
... 
>>> f = Foo()
>>> 
>>> print getsource(f.bar)
def bar(self, x):
    return x*x+x

>>> 


0

さらに、リストと辞書の内部を見たい場合は、pprint()を使用できます


0

すでに多くの良いヒントがありますが、最も短くて簡単な(必ずしも最良ではない)にはまだ言及していません。

object?

-3

使ってみてください:

print(object.stringify())
  • ここobjectで、検査しようとしているオブジェクトの変数名です。

これにより、オブジェクトのキーと値のすべての階層を示す、適切にフォーマットされたタブ付きの出力が出力されます。

注:これはpython3で動作します。それが以前のバージョンで動作するかどうかわからない

更新:これは、すべてのタイプのオブジェクトで機能するわけではありません。これらのタイプのいずれかに遭遇した場合(Requestオブジェクトなど)、代わりに次のいずれかを使用してください。

  • dir(object())

または

import pprint 次に: pprint.pprint(object.__dict__)


1
「リクエスト」オブジェクトでは機能しません「「リクエスト」オブジェクトには属性 '
stringify
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.