14

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

3 回答 3

19

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

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))
于 2016-03-04T19:11:44.647 回答
8

您的代码对我有用,除了以错误的顺序打印(内部优先,这是我对递归的实际期望)。

所以,我改变了顺序(并使用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
于 2013-05-03T08:44:41.183 回答
4

总是更好地使用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)

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

您可以查看文档

于 2013-05-03T08:42:45.440 回答