是否有内置功能可以打印对象的所有当前属性和值?

问题:是否有内置功能可以打印对象的所有当前属性和值?

所以我在这里寻找的是类似PHP的print_r函数。

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

So what I’m looking for here is something like PHP’s print_r function.

This is so I can debug my scripts by seeing what’s the state of the object in question.


回答 0

您实际上是将两种不同的东西混合在一起。

使用dir()vars()inspect模块来得到你所感兴趣的是(我用__builtins__作为一个例子,你可以使用任何对象,而不是)。

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

随心所欲地打印该词典:

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

要么

>>> 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',
...

交互式调试器中还可以作为命令提供漂亮的打印:

(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__'}

You are really mixing together two different things.

Use dir(), vars() or the inspect module to get what you are interested in (I use __builtins__ as an example; you can use any object instead).

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

Print that dictionary however fancy you like:

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

or

>>> 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',
...

Pretty printing is also available in the interactive debugger as a command:

(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

您要vars()pprint()

from pprint import pprint
pprint(vars(your_object))

You want vars() mixed with pprint():

from pprint import pprint
pprint(vars(your_object))

回答 2

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

有很多第三方函数可以根据其作者的喜好添加诸如异常处理,国家/特殊字符打印,递归到嵌套对象等功能。但他们基本上都归结为这一点。

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

There are many 3rd-party functions out there that add things like exception handling, national/special character printing, recursing into nested objects etc. according to their authors’ preferences. But they all basically boil down to this.


回答 3

已经提到了dir,但这只会为您提供属性的名称。如果还需要它们的值,请尝试__dict__。

class O:
   def __init__ (self):
      self.value = 3

o = O()

这是输出:

>>> o.__dict__

{'value': 3}

dir has been mentioned, but that’ll only give you the attributes’ names. If you want their values as well try __dict__.

class O:
   def __init__ (self):
      self.value = 3

o = O()

Here is the output:

>>> o.__dict__

{'value': 3}

回答 4

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

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

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

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

You can use the “dir()” function to do this.

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

Another useful feature is help.

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

回答 5

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

>>> obj # in an interpreter

要么

print repr(obj) # in a script

要么

print obj

为您的类定义__str____repr__方法。从Python文档中

__repr__(self)repr()内置函数和字符串转换(反引号)调用以计算对象的“正式”字符串表示形式。如果可能的话,这应该看起来像一个有效的Python表达式,可以用来重新创建具有相同值的对象(在适当的环境下)。如果无法做到这一点,则应返回“ <…一些有用的说明…>”形式的字符串。返回值必须是一个字符串对象。如果一个类定义了repr()而不是__str__(),那么__repr__()当需要该类实例的“非正式”字符串表示形式时,也可以使用该类。这通常用于调试,因此重要的是,表示形式必须信息丰富且明确。

__str__(self)str()内置函数和print语句调用,以计算对象的“非正式”字符串表示形式。区别__repr__()在于它不必是有效的Python表达式:相反,可以使用更方便或更简洁的表示形式。返回值必须是一个字符串对象。

To print the current state of the object you might:

>>> obj # in an interpreter

or

print repr(obj) # in a script

or

print obj

For your classes define __str__ or __repr__ methods. From the Python documentation:

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


回答 6

可能值得一看-

是否有与Perl的Data :: Dumper等效的Python?

我的建议是

https://gist.github.com/1071857

请注意,perl有一个称为Data :: Dumper的模块,该模块将对象数据转换回perl源代码(注意:它不会将代码转换回源代码,并且几乎始终不希望输出中的对象方法函数)。可以将其用于持久性,但通用目的是用于调试。

标准python pprint有很多无法实现的功能,特别是当它看到一个对象的实例并为您提供该对象的内部十六进制指针时,它只会停止下降(错误,该指针不是很多使用方式)。简而言之,python就是关于这个伟大的面向对象范例的全部,但是您开箱即用的工具是为处理对象以外的东西而设计的。

perl Data :: Dumper允许您控制要深入的深度,还可以检测圆形链接结构(这很重要)。从根本上讲,此过程在perl中更容易实现,因为对象没有祝福以外的任何魔力(普遍定义良好的过程)。

Might be worth checking out —

Is there a Python equivalent to Perl’s Data::Dumper?

My recommendation is this —

https://gist.github.com/1071857

Note that perl has a module called Data::Dumper which translates object data back to perl source code (NB: it does NOT translate code back to source, and almost always you don’t want to the object method functions in the output). This can be used for persistence, but the common purpose is for debugging.

There are a number of things standard python pprint fails to achieve, in particular it just stops descending when it sees an instance of an object and gives you the internal hex pointer of the object (errr, that pointer is not a whole lot of use by the way). So in a nutshell, python is all about this great object oriented paradigm, but the tools you get out of the box are designed for working with something other than objects.

The perl Data::Dumper allows you to control how deep you want to go, and also detects circular linked structures (that’s really important). This process is fundamentally easier to achieve in perl because objects have no particular magic beyond their blessing (a universally well defined process).


回答 7

我建议使用help(your_object)

help(dir)

 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)

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

I recommend using help(your_object).

help(dir)

 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)

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

回答 8

在大多数情况下,使用__dict__dir()将获得所需的信息。如果您碰巧需要更多细节,则标准库包含检查模块,可让您获得一些令人印象深刻的细节。真正真正的信息包括:

  • 函数名称和方法参数
  • 类层次结构
  • 函数/类对象的实现源代码
  • 框架对象外的局部变量

如果你只是寻找“难道我的对象有什么属性值?”,然后dir()__dict__可能是足够的。如果您真的想深入研究任意对象的当前状态(请记住,在python中几乎所有对象都是对象),那么inspect值得考虑。

In most cases, using __dict__ or dir() will get you the info you’re wanting. If you should happen to need more details, the standard library includes the inspect module, which allows you to get some impressive amount of detail. Some of the real nuggests of info include:

  • names of function and method parameters
  • class hierarchies
  • source code of the implementation of a functions/class objects
  • local variables out of a frame object

If you’re just looking for “what attribute values does my object have?”, then dir() and __dict__ are probably sufficient. If you’re really looking to dig into the current state of arbitrary objects (keeping in mind that in python almost everything is an object), then inspect is worthy of consideration.


回答 9

是否有内置功能可以打印对象的所有当前属性和值?

不可以。最受好评的答案不包括某些类型的属性,被接受的答案显示了如何获取所有属性,包括非公共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仅返回与一个对象关联的所有(实际上只是大多数)名称。

inspect.getmembers注释中提到的,也存在类似缺陷-它返回所有名称值。

从Class

在教学时,我让我的学生创建一个函数,该函数提供对象的语义公共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': ''}

注意事项

但是也许我们确实知道我们的财产并不昂贵。我们可能想要更改逻辑以使其也包括在内。也许我们想排除其他 自定义数据描述符。

然后,我们需要进一步自定义此功能。因此,我们不能拥有一个内在的功能,就可以神奇地准确地知道我们想要什么并提供它,这是有道理的。这是我们需要创建自己的功能。

结论

没有内置函数可以执行此操作,因此您应该执行最适合您情况的语义上的操作。

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

No. The most upvoted answer excludes some kinds of attributes, and the accepted answer shows how to get all attributes, including methods and parts of the non-public api. But there is no good complete builtin function for this.

So the short corollary is that you can write your own, but it will calculate properties and other calculated data-descriptors that are part of the public API, and you might not want that:

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

Problems with other answers

Observe the application of the currently top voted answer on a class with a lot of different kinds of data members:

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

only prints:

{'baz': 'baz'}

Because vars only returns the __dict__ of an object, and it’s not a copy, so if you modify the dict returned by vars, you’re also modifying the __dict__ of the object itself.

vars(obj)['quux'] = 'WHAT?!'
vars(obj)

returns:

{'baz': 'baz', 'quux': 'WHAT?!'}

— which is bad because quux is a property that we shouldn’t be setting and shouldn’t be in the namespace…

Applying the advice in the currently accepted answer (and others) is not much better:

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

As we can see, dir only returns all (actually just most) of the names associated with an object.

inspect.getmembers, mentioned in the comments, is similarly flawed – it returns all names and values.

From class

When teaching I have my students create a function that provides the semantically public API of an object:

def api(obj):
    return [name for name in dir(obj) if name[0] != '_']

We can extend this to provide a copy of the semantic namespace of an object, but we need to exclude __slots__ that aren’t assigned, and if we’re taking the request for “current properties” seriously, we need to exclude calculated properties (as they could become expensive, and could be interpreted as not “current”):

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

And now we do not calculate or show the property, quux:

>>> attrs(obj)
{'bar': 0, 'baz': 'baz', 'foo': ''}

Caveats

But perhaps we do know our properties aren’t expensive. We may want to alter the logic to include them as well. And perhaps we want to exclude other custom data descriptors instead.

Then we need to further customize this function. And so it makes sense that we cannot have a built-in function that magically knows exactly what we want and provides it. This is functionality we need to create ourselves.

Conclusion

There is no built-in function that does this, and you should do what is most semantically appropriate for your situation.


回答 10

一个带有魔术的元编程示例Dump对象

$ 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实用程序

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

它有点过时了,但仍然可以使用。

A metaprogramming example Dump object with magic:

$ 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

Without arguments:

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

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

It is a bit outdated but still working.


回答 11

如果您正在使用它进行调试,并且只想递归地转储所有内容,那么可接受的答案将不令人满意,因为这要求您的类已经具有良好的__str__实现。如果不是这种情况,那么效果会更好:

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

If you’re using this for debugging, and you just want a recursive dump of everything, the accepted answer is unsatisfying because it requires that your classes have good __str__ implementations already. If that’s not the case, this works much better:

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

回答 12

尝试ppretty

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)

输出:

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

Try ppretty

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)

Output:

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

回答 13

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

回答 14

这将以json或yaml缩进格式递归打印所有对象内容:

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)

This prints out all the object contents recursively in json or yaml indented format:

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)

回答 15

我赞成仅提及pprint的答案。明确地说,如果要查看复杂数据结构中的所有,请执行以下操作:

from pprint import pprint
pprint(my_var)

其中my_var是您感兴趣的变量。当我使用时,pprint(vars(my_var))我什么也没得到,这里的其他答案也无济于事,或者该方法看起来不必要地冗长。顺便说一句,在我的特定情况下,我正在检查的代码具有字典词典。

值得指出的是,对于某些自定义类,您可能只会得到无用<someobject.ExampleClass object at 0x7f739267f400>的输出。在这种情况下,您可能必须实现一个__str__方法或尝试其他解决方案。我仍然想找到没有第三方库就可以在所有情况下使用的简单方法。

I’ve upvoted the answer that mentions only pprint. To be clear, if you want to see all the values in a complex data structure, then do something like:

from pprint import pprint
pprint(my_var)

Where my_var is your variable of interest. When I used pprint(vars(my_var)) I got nothing, and other answers here didn’t help or the method looked unnecessarily long. By the way, in my particular case, the code I was inspecting had a dictionary of dictionaries.

Worth pointing out that with some custom classes you may just end up with an unhelpful <someobject.ExampleClass object at 0x7f739267f400> kind of output. In that case, you might have to implement a __str__ method, or try some of the other solutions. I’d still like to find something simple that works in all scenarios, without third party libraries.


回答 16

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

DO = DemoObject()

itemDir = DO.__dict__

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

I was needing to print DEBUG info in some logs and was unable to use pprint because it would break it. Instead I did this and got virtually the same thing.

DO = DemoObject()

itemDir = DO.__dict__

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

回答 17

要转储“ myObject”:

from bson import json_util
import json

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

我尝试了vars()和dir(); 都因为我要找的东西而失败了。vars()无效,因为对象没有__dict__(exceptions.TypeError:vars()参数必须具有__dict__属性)。dir()并不是我要找的东西:它只是字段名的列表,不提供值或对象结构。

我认为json.dumps()适用于没有default = json_util.default的大多数对象,但是我在对象中有一个datetime字段,因此标准json序列化程序失败。请参阅如何克服python中的“ datetime.datetime无法JSON序列化”?

To dump “myObject”:

from bson import json_util
import json

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

I tried vars() and dir(); both failed for what I was looking for. vars() didn’t work because the object didn’t have __dict__ (exceptions.TypeError: vars() argument must have __dict__ attribute). dir() wasn’t what I was looking for: it’s just a listing of field names, doesn’t give the values or the object structure.

I think json.dumps() would work for most objects without the default=json_util.default, but I had a datetime field in the object so the standard json serializer failed. See How to overcome “datetime.datetime not JSON serializable” in python?


回答 18

为什么不简单一些:

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

Why not something simple:

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

回答 19

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

pprint contains a “pretty printer” for producing aesthetically pleasing representations of your data structures. The formatter produces representations of data structures that can be parsed correctly by the interpreter, and are also easy for a human to read. The output is kept on a single line, if possible, and indented when split across multiple lines.


回答 20

只需尝试beeprint

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

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

Just try beeprint.

It will help you not only with printing object variables, but beautiful output as well, like this:

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

回答 21

对于每个奋斗的人

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

以下代码显示带有的所有属性obj及其值:

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

For everybody struggling with

  • vars() not returning all attributes.
  • dir() not returning the attributes’ values.

The following code prints all attributes of obj with their values:

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

回答 22

您可以尝试Flask调试工具栏。
https://pypi.python.org/pypi/Flask-DebugToolbar

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)

You can try the Flask Debug Toolbar.
https://pypi.python.org/pypi/Flask-DebugToolbar

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)

回答 23

我喜欢使用python对象内置类型keysvalues

对于属性,无论它们是方法还是变量:

o.keys()

对于这些属性的值:

o.values()

I like working with python object built-in types keys or values.

For attributes regardless they are methods or variables:

o.keys()

For values of those attributes:

o.values()

回答 24

无论在类中,__init__或外部如何定义变量,该方法都有效。

your_obj = YourObj()
attrs_with_value = {attr: getattr(your_obj, attr) for attr in dir(your_obj)}

This works no matter how your varibles are defined within a class, inside __init__ or outside.

your_obj = YourObj()
attrs_with_value = {attr: getattr(your_obj, attr) for attr in dir(your_obj)}