2013-05-03 14 views
7

これを行う標準的な方法があるかどうかわかりません。オブジェクトのすべての内容をダンプする次の関数を実装しました。これは、再帰的にサブオブジェクトをダンプしなければならないので、私はInstanceTypeをチェックしていますが、それは動作しません:要素はオブジェクトそのものである場合オブジェクトを再帰的にダンプする

import types 

def dump_obj(obj, level=0): 
    for a in dir(obj): 
     try: 
      if type(obj.__dict__[a]) == types.InstanceType: 
       dump_obj(obj.__dict__[a], level + 2) 
      else: 
       try: 
        print " " * level + "%s -> %s" % (a, obj.__dict__[a]) 
       except: 
        pass 
     except: 
      pass 

はどうやって確認することができますか?

私が実際に欲しいのは以下のとおりです。与えられた:

class B: 
    def __init__(self): 
    self.txt = 'bye' 

class A: 
    def __init__(self): 
    self.txt = 'hello' 
    self.b = B() 

a = A() 

dump_obj(a) 

私は、次のような出力をしたい:

txt -> hello 
    txt -> bye 
+0

すべてがPythonのオブジェクトです。 – Matthias

+0

Ok:要素が 'types.InstanceType'(または必要なもの)であるかどうかを確認することができます。再帰をトリガーできますか? – dangonfast

答えて

2

type(x) == yの代わりにisinstance(x, y)を使用するのが無難です。

すべてがPythonのオブジェクトなので、isinstance(attr, object)は意味がありません。なぜなら、私はそれが常に真を返すからです。

あなたの最善の策は特定のタイプを「ブラックリストに登録する」ことです。たとえば、それがint, float, str, unicode, list, dict, set, ...以外であるかどうかを確認します。そうでない場合は、それを印刷します。例えば

def dump(obj, level=0): 
    for attr in dir(obj): 
     val = getattr(obj, a) 
     if isinstance(val, (int, float, str, unicode, list, dict, set)): 
      print level*' ', val 
     else: 
      dump(val, level=level+1) 

UPDATEisinstanceは、アカウントの継承にかかるので、あなたは、オブジェクトが親クラスのインスタンスであるかどうかを確認しようとした場合、それは時にないかもしれないが、それはTrueを返しますタイプを使用します。

この場合、プリミティブ型に対してテストされますので、この場合は違いはありませんが、一般的にはisinstanceが望ましいです。

この例を参照してください:

>>> class A(object): pass 
... 
>>> class B(A): pass 
... 
>>> a, b = A(), B() 
>>> type(a) 
<class '__main__.A'> 
>>> type(a) == A 
True 
>>> type(b) 
<class '__main__.B'> 
>>> type(b) == B 
True 
>>> type(b) == A 
False 
>>> 

あなたはdocs

+0

おかげで、私はこれに似た何かをやってますが、 ''タイプ()==を使用して終わりました。なぜisinstanceを使うのが良いのかを詳しく説明できますか? – dangonfast

+0

あなたは正しいです、そして私の例を簡略化しました。実際に私は標準ライブラリから複雑なオブジェクトをダンプしたい、あなたの注意点が関連しているので。一方、 'getattr'も無限再帰を引き起こす方法や他のものを返します。 ' – dangonfast

+0

はDIR(OBJ)にするためにああ素敵な発見:) – jadkik94

5

あなたのコードは、物事は私が実際にどうなるかで間違った順序(インナー最初に印刷され得ることを除いて、私の作品をチェックアウトすることができます再帰で期待する)。

だから、私は順序を変更(およびisinstance()など__dict__を反復処理を使用):

import types 

def dump_obj(obj, level=0): 
    for key, value in obj.__dict__.items(): 
     if not isinstance(value, types.InstanceType): 
      print " " * level + "%s -> %s" % (key, value) 
     else: 
      dump_obj(value, level + 2) 

class B: 
    def __init__ (self): 
    self.txt = 'bye' 

class A: 
    def __init__(self): 
    self.txt = 'hello' 
    self.b = B() 

a = A() 

dump_obj(a) 

これは再帰的に任意のオブジェクトおよびすべてのサブオブジェクトをダンプします

txt -> hello 
    txt -> bye 
+0

これは簡単な例のために働いたが、複雑なオブジェクトのために、それはで一部のデータが欠落していました:代わりに'のは、DIR(OBJ)内のattrのために ': – wisbucky

5

を生成します。他の答えは簡単な例ではうまくいきましたが、複雑なオブジェクトの場合、データが欠落していました。

import jsonpickle # pip install jsonpickle 
import json 

serialized = jsonpickle.encode(obj) 
print json.dumps(json.loads(serialized), indent=2) 

編集:YAML形式を使用すると、あなたの例にさらに近くなります。

import yaml # pip install pyyaml 
print yaml.dump(yaml.load(serialized), indent=2) 
+2

これは受け入れられる回答でなければなりません –

関連する問題