Python 递归地转储对象

Python 递归地转储对象,python,Python,我不确定是否有一个标准的方法来做这件事。我实现了以下函数来转储对象的所有内容。它必须递归地转储子对象,因此我正在检查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.__di

我不确定是否有一个标准的方法来做这件事。我实现了以下函数来转储对象的所有内容。它必须递归地转储子对象,因此我正在检查
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

最好使用
isinstance(x,y)
而不是
type(x)==y

因为在Python中,一切都是对象,所以执行
isinstance(attr,object)
是没有意义的,因为(我猜)它总是返回true

你最好的办法是将某些类型的产品列入“黑名单”。例如,您检查它是否不是
int、float、str、unicode、list、dict、set,…
您可以更深入,否则只需打印它

例如:

def dump(obj, level=0):
   for a 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)
更新
isinstance
考虑继承,因此如果尝试查看对象是否为父类的实例,则在使用type时,它将返回True,而可能不会返回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
>>> 
>>A类(对象):通过
... 
>>>B(A)级:及格
... 
>>>a,b=a(),b()
>>>类型(a)
>>>类型(a)==a
真的
>>>类型(b)
>>>类型(b)==b
真的
>>>类型(b)==A
假的
>>> 

你可以检查一下你的代码是否对我有用,除了以错误的顺序打印(内部优先,这是我实际期望的递归)

因此,我更改了顺序(并使用了
isinstance()
以及迭代
\uuu dict\uuu
):

产生

txt -> hello
  txt -> bye

这将递归地转储任何对象和所有子对象。其他答案适用于简单的示例,但对于复杂的对象,它们缺少一些数据

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

在Python中,一切都是对象。好的:如何验证元素是否属于
类型。InstanceType
(或任何需要的),以便触发递归?谢谢,我结束了类似的操作,但使用了
type()=
。你能详细解释一下为什么使用
isinstance
更好吗?你说得对,我的例子简化了:实际上我想从标准库中转储复杂对象,所以你的警告是相关的。另一方面,
getattr
还返回方法和其他东西,这会导致无限递归。
对于in-dir(obj):
而不是
对于attr-in-dir(obj):
这对于简单的示例有效,但是对于复杂的对象,它在子对象中丢失了一些数据。这很好!在上面的回答中得到了AttributeError。
import yaml # pip install pyyaml
print(yaml.dump(yaml.load(serialized), indent=2))