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

Is there a built-in function to print all the current properties and values of an object?

所以我要找的是类似于php的print_r函数的东西。这样我就可以通过查看有问题的对象的状态来调试脚本。


您要将vars()pprint()混合:

1
2
from pprint import pprint
pprint(vars(your_object))


你真的把两种不同的东西混在一起了。

使用dir()vars()inspect模块获取您感兴趣的内容(我以__builtins__为例,您可以使用任何对象代替)。

1
2
>>> l = dir(__builtins__)
>>> d = __builtins__.__dict__

不管你喜欢什么,都可以把那本字典打印出来:

1
2
>>> print l
['ArithmeticError', 'AssertionError', 'AttributeError',...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
>>> from pprint import pprint
>>> pprint(l)
['ArithmeticError',
 'AssertionError',
 'AttributeError',
 'BaseException',
 'DeprecationWarning',
...

>>> pprint(d, indent=2)
{ 'ArithmeticError': <type 'exceptions.ArithmeticError'>,
  'AssertionError': <type 'exceptions.AssertionError'>,
  'AttributeError': <type 'exceptions.AttributeError'>,
...
  '_': [ 'ArithmeticError',
         'AssertionError',
         'AttributeError',
         'BaseException',
         'DeprecationWarning',
...

Interactive Debugger中还提供了漂亮的打印命令:

1
2
3
4
5
6
7
8
9
10
(Pdb) pp vars()
{'__builtins__': {'ArithmeticError': <type 'exceptions.ArithmeticError'>,
                  'AssertionError': <type 'exceptions.AssertionError'>,
                  'AttributeError': <type 'exceptions.AttributeError'>,
                  'BaseException': <type 'exceptions.BaseException'>,
                  'BufferError': <type 'exceptions.BufferError'>,
                  ...
                  'zip': <built-in function zip>},
 '__file__': 'pass.py',
 '__name__': '__main__'}


1
2
3
def dump(obj):
  for attr in dir(obj):
    print("obj.%s = %r" % (attr, getattr(obj, attr)))

有许多第三方函数可以根据作者的喜好添加异常处理、国家/特殊字符打印、递归到嵌套对象等内容。但它们基本上都归结为这个。


已经提到dir,但这只会给出属性的名称。如果你也想要他们的价值观,那就试试"听写"。

1
2
3
4
5
class O:
   def __init__ (self):
      self.value = 3

o = O()

以下是输出:

1
2
3
>>> o.__dict__

{'value': 3}


要打印对象的当前状态,您可以:

1
>>> obj # in an interpreter

1
print repr(obj) # in a script

1
print obj

对于类,定义__str____repr__方法。从python文档中:

__repr__(self) Called by the repr() built-in function and by string
conversions (reverse quotes) to
compute the"official" string
representation of an object. If at all
possible, this should look like a
valid Python expression that could be
used to recreate an object with the
same value (given an appropriate
environment). If this is not possible,
a string of the form"<...some useful description...>" should be returned.
The return value must be a string
object. If a class defines repr()
but not __str__(), then __repr__() is
also used when an"informal" string
representation of instances of that
class is required. This is typically
used for debugging, so it is important
that the representation is
information-rich and unambiguous.

__str__(self) Called by the str() built-in function and by the print
statement to compute the"informal"
string representation of an object.
This differs from __repr__() in that
it does not have to be a valid Python
expression: a more convenient or
concise representation may be used
instead. The return value must be a
string object.


您可以使用"dir()"函数来执行此操作。

1
2
3
4
5
6
7
8
9
10
11
12
>>> import sys
>>> dir(sys)
['__displayhook__', '__doc__', '__excepthook__', '__name__', '__stderr__', '__stdin__', '__stdo
t__'
, '_current_frames', '_getframe', 'api_version', 'argv', 'builtin_module_names', 'byteorder
, '
call_tracing', 'callstats', 'copyright', 'displayhook', 'dllhandle', 'exc_clear', 'exc_info'
 '
exc_type', 'excepthook', 'exec_prefix', 'executable', 'exit', 'getcheckinterval', 'getdefault
ncoding', 'getfilesystemencoding', 'getrecursionlimit', 'getrefcount', 'getwindowsversion', 'he
version', 'maxint', 'maxunicode', 'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_
ache', 'platform', 'prefix', 'ps1', 'ps2', 'setcheckinterval', 'setprofile', 'setrecursionlimit
, 'settrace', 'stderr', 'stdin', 'stdout', 'subversion', 'version', 'version_info', 'warnoption
'
, 'winver']
>>>

另一个有用的功能是帮助。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
>>> help(sys)
Help on built-in module sys:

NAME
    sys

FILE
    (built-in)

MODULE DOCS
    http://www.python.org/doc/current/lib/module-sys.html

DESCRIPTION
    This module provides access to some objects used or maintained by the
    interpreter and to functions that interact strongly with the interpreter.

    Dynamic objects:

    argv -- command line arguments; argv[0] is the script pathname if known

可能值得一看--

是否有一个与Perl的data::dumper等效的python?

我的建议是--

网址:https://gist.github.com/1071857

注意,Perl有一个名为Data::Dumper的模块,它将对象数据转换回Perl源代码(注意:它不将代码转换回源代码,而且几乎总是不希望输出中的对象方法函数)。这可以用于持久性,但通常用于调试。

标准python pprint无法实现的事情有很多,特别是当它看到一个对象的实例并给您对象的内部十六进制指针时,它会停止下降(errr,顺便说一下,这个指针并不是很有用)。所以简而言之,Python就是关于这个面向对象的伟大范例的,但是你从盒子里得到的工具是为处理对象以外的东西而设计的。

PerlData::Dumper允许您控制您想深入的程度,还可以检测循环链接结构(这非常重要)。在Perl中,这个过程基本上更容易实现,因为对象除了它们的福祉(一个普遍定义良好的过程)之外没有特殊的魔力。


在大多数情况下,使用__dict__dir()可以获得您想要的信息。如果您碰巧需要更多的细节,那么标准库就包含了inspect模块,它允许您获得一些令人印象深刻的细节。一些真正的信息来源包括:

  • 函数名和方法参数
  • 类层次
  • 函数/类对象实现的源代码
  • 帧对象中的局部变量

如果您只是在寻找"我的对象有哪些属性值?"那么,dir()__dict__可能就足够了。如果您真的想深入了解任意对象的当前状态(记住,在Python中,几乎所有东西都是一个对象),那么inspect是值得考虑的。


元编程示例使用magic转储对象:

1
$ cat dump.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/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

不带参数:

1
$ python dump.py
1
<__main__.Data instance at 0x00A052D8>

使用gnosis utils:

1
$ python dump.py gnosis.magic MetaXMLPickler
1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0"?>
<!DOCTYPE PyObject SYSTEM"PyObjects.dtd">
<PyObject module="__main__" class="Data" id="11038416">

  <item type="string" value="a" />
  <item type="string" value="b" />
  <item type="string" value="c" />
</attr>


</PyObject>

它有点过时,但仍在工作。


如果您正在使用它进行调试,并且只希望递归转储所有内容,那么接受的答案是不满意的,因为它要求类已经具有良好的__str__实现。如果不是这样的话,这就更好了:

1
2
3
4
import json
print(json.dumps(YOUR_OBJECT,
                 default=lambda obj: vars(obj),
                 indent=1))


这将以JSON或YAML缩进格式递归打印出所有对象内容:

1
2
3
4
5
6
7
import jsonpickle # pip install jsonpickle
import json
import yaml # pip install pyyaml

serialized = jsonpickle.encode(obj, max_depth=2) # max_depth is optional
print json.dumps(json.loads(serialized), indent=4)
print yaml.dump(yaml.load(serialized), indent=4)

要转储"myObject":

1
2
3
4
from bson import json_util
import json

print(json.dumps(myObject, default=json_util.default, sort_keys=True, indent=4, separators=(',', ': ')))

我尝试了vars()和dir();两者都失败了。vars()不起作用,因为对象没有uudict_uuuuuu(exceptions.typeerror:vars()参数必须具有uudict_uuuu属性)。dir()不是我要找的:它只是一个字段名列表,没有给出值或对象结构。

我认为json.dumps()适用于大多数没有默认值=json_Util.default的对象,但是我在对象中有一个datetime字段,所以标准的json序列化程序失败。看看如何克服python中的"datetime.datetime而不是json serializable"?


我需要在一些日志中打印调试信息,无法使用pprint,因为它会破坏它。相反,我做了这个,得到了几乎相同的东西。

1
2
3
4
5
6
DO = DemoObject()

itemDir = DO.__dict__

for i in itemDir:
    print '{0}  :  {1}'.format(i, itemDir[i])

1
2
3
4
5
from pprint import pprint

def print_r(the_object):
    print ("CLASS:", the_object.__class__.__name__," (BASE CLASS:", the_object.__class__.__bases__,")")
    pprint(vars(the_object))


试一试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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(), show_protected=True, show_static=True, show_properties=True)

输出:

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

我建议使用help(your_object)

help(dir)

1
2
3
4
5
6
7
8
9
10
 If called without an argument, return the names in the current scope.
 Else, return an alphabetized list of names comprising (some of) the attributes
 of the given object, and of attributes reachable from it.
 If the object supplies a method named __dir__, it will be used; otherwise
 the default dir() logic is used and returns:
 for a module object: the module's attributes.
 for a class object:  its attributes, and recursively the attributes
 of its bases.
 for any other object: its attributes, its class'
s attributes, and
 recursively the attributes of its class's base classes.

help(vars)

1
2
Without arguments, equivalent to locals().
With an argument, equivalent to object.__dict__.

pprint包含一个"漂亮的打印机",用于生成数据结构的美观表示。格式化程序生成数据结构的表示,这些数据结构可由解释器正确解析,并且便于人阅读。如果可能的话,输出保持在一行上,并在跨多行拆分时缩进。


试试"哔哔"声。

它不仅可以帮助您打印对象变量,还可以帮助您获得漂亮的输出,如:

1
2
3
4
5
6
class(NormalClassNewStyle):
  dicts: {
  },
  lists: [],
  static_props: 1,
  tupl: (1, 2)


我已经否决了只提到pprint的答案。要清楚,如果您希望看到复杂数据结构中的所有值,请执行以下操作:

1
2
from pprint import pprint
pprint(my_var)

其中,我的变量是你的兴趣变量。当我使用pprint(vars(我的var))时,我什么也没有得到,这里的其他答案也没有帮助,或者方法看起来不必要太长。顺便说一下,在我的特殊情况下,我检查的代码有一本字典。

值得指出的是,对于一些定制类,您可能最终得到一种无用的类型的输出。在这种情况下,您可能需要实现一个__str__方法,或者尝试其他一些解决方案。我仍然想找到一些简单的东西,在没有第三方库的情况下,可以在所有场景中工作。


为什么不简单点:

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


为每个奋斗的人

  • vars()不返回所有属性。
  • dir()不返回属性值。

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

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

您可以尝试"烧瓶调试"工具栏。https://pypi.python.org/pypi/flask-debugtoolbar

1
2
3
4
5
6
7
8
9
10
11
12
from flask import Flask
from flask_debugtoolbar import DebugToolbarExtension

app = Flask(__name__)

# the toolbar is only enabled in debug mode:
app.debug = True

# set a 'SECRET_KEY' to enable the Flask session cookies
app.config['SECRET_KEY'] = '<replace with a secret key>'

toolbar = DebugToolbarExtension(app)

我喜欢使用Python对象内置类型键或值。

对于属性,不管它们是方法或变量:

1
o.keys()

对于这些属性的值:

1
o.values()