这里我要找的是PHP的print_r函数。

这样我就可以通过查看有问题的对象的状态来调试脚本。


当前回答

Pprint包含一个“漂亮的打印机”,用于生成令人满意的数据结构表示。格式化程序生成的数据结构表示可以被解释器正确解析,并且易于人类阅读。如果可能的话,输出将保持在单行上,并在跨多行分割时缩进。

其他回答

对于每个挣扎的人

Vars()不返回所有属性。 Dir()不返回属性的值。

下面的代码打印obj的所有属性及其值:

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

一个有魔力的元编程示例转储对象:

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

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

虽然有点过时,但还能用。

你需要vars()和pprint()的混合:

from pprint import pprint
pprint(vars(your_object))

为什么不简单点呢:

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

是否有内置函数打印对象的所有当前属性和值?

不。投票最多的答案排除了某些类型的属性,而接受的答案显示了如何获取所有属性,包括方法和部分非公共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,你也在修改对象本身的__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只返回与对象相关的所有(实际上是大部分)名称。

检查。评论中提到的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': ''}

警告

但也许我们知道我们的房产并不贵。我们可能想要改变逻辑以包括它们。也许我们希望排除其他自定义数据描述符。

然后我们需要进一步定制这个函数。因此,我们不能有一个内置函数神奇地知道我们想要什么并提供它。这是我们需要自己创造的功能。

结论

没有内置函数可以做到这一点,您应该根据自己的情况选择语义上最合适的方法。