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

发布于 2024-07-06 16:19:51 字数 131 浏览 7 评论 0原文

所以我在这里寻找的是类似 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(30

禾厶谷欠 2024-07-13 16:19:51

您希望将 vars()pprint() 混合:

from pprint import pprint
pprint(vars(your_object))

You want vars() mixed with pprint():

from pprint import pprint
pprint(vars(your_object))
放飞的风筝 2024-07-13 16:19:51

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

使用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__'}
红玫瑰 2024-07-13 16:19:51
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.

小猫一只 2024-07-13 16:19:51

已经提到了 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}
星星的轨迹 2024-07-13 16:19:51

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

否。获得最多支持的答案排除了某些类型的属性,而接受的答案显示了如何获取所有属性,包括方法和非公共 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 only 返回对象的 __dict__,并且它是不是副本,因此如果您修改 vars 返回的字典,您也会修改对象本身的 __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 也有类似的缺陷 - 它返回所有名称​​和值。

在课堂上

教学时,我让学生创建一个提供对象的语义公共 API 的函数:

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

我们可以扩展它以提供对象的语义命名空间的副本,但我们需要排除< code>__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.

苹果你个爱泡泡 2024-07-13 16:19:51

您可以使用“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
凡间太子 2024-07-13 16:19:51

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

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

伊面 2024-07-13 16:19:51

我建议使用 help(your_object)

帮助(目录)

 如果调用时不带参数,则返回当前作用域中的名称。 
   否则,返回包含(某些)属性的按字母顺序排列的名称列表 
   给定对象以及可从该对象访问的属性。 
   如果该对象提供了名为 __dir__ 的方法,则将使用该方法;   否则 
   使用默认的 dir() 逻辑并返回: 
   对于模块对象:模块的属性。 
   对于类对象:其属性,以及递归属性 
   其基地。 
   对于任何其他对象:它的属性、它的类的属性,以及 
   递归地获取其类的基类的属性。 
  

帮助(变量)

不带参数,相当于 locals()。 
  带参数,相当于 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__.
梦醒时光 2024-07-13 16:19:51

可能值得一试 -

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

我的建议是这样的 --

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

三寸金莲 2024-07-13 16:19:51

在大多数情况下,使用 __dict__ 或 dir() 将为您提供所需的信息。 如果您碰巧需要更多详细信息,标准库包含 inspect 模块,这可以让你获得一些令人印象深刻的细节。 一些真正有价值的信息包括:

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

如果您只是在寻找“我的对象有什么属性值” ?”,那么 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.

不必在意 2024-07-13 16:19:51

如果您使用它进行调试,并且您只想对所有内容进行递归转储,则接受的答案并不令人满意,因为它要求您的类已经具有良好的 __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))
如日中天 2024-07-13 16:19:51

尝试 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)
蒗幽 2024-07-13 16:19:51

元编程示例 神奇转储对象

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

带 < a href="http://www.gnosis.cx/download/Gnosis_Utils.More/" rel="noreferrer">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>

它有点过时,但仍然有效。

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.

跨年 2024-07-13 16:19:51

这会以 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)
北城挽邺 2024-07-13 16:19:51
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))
耶耶耶 2024-07-13 16:19:51

为什么不做一些简单的事情:

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

Why not something simple:

for key,value in obj.__dict__.iteritems():
    print key,value
末骤雨初歇 2024-07-13 16:19:51

无论变量在类中、 __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)}
南烟 2024-07-13 16:19:51

如果您想查看复杂数据结构中的所有,请执行以下操作:

from pprint import pprint
pprint(my_var)

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

值得指出的是,对于某些自定义类,您可能最终会得到无用的 类型的输出。 在这种情况下,您可能必须实现 __str__ 方法,或尝试其他一些解决方案。

我还发现,在一个获得 object 类型输出的实例中,vars() 显示了我想要的内容。 因此,涵盖这两种情况的更好解决方案是分别尝试这两种情况。 但使用vars()有时会抛出异常,例如TypeError: vars() argument must have __dict__ attribute

我仍然想找到一些简单的东西,可以在所有场景中使用,而不需要第三方库。

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 also found that in one instance where I got this object type of output, vars() showed me what I wanted. So a better solution to cover both cases would be to try both individually. But using vars() can sometimes throw an exception, for example, TypeError: vars() argument must have __dict__ attribute.

I'd still like to find something simple that works in all scenarios, without third party libraries.

黑色毁心梦 2024-07-13 16:19:51

我需要在某些日志中打印调试信息,但无法使用 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])
叫思念不要吵 2024-07-13 16:19:51

要转储“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 的对象,但我在对象中有一个日期时间字段,因此标准 json 序列化器失败了。 请参阅 如何克服“datetime.datetime 不可 JSON 序列化”在Python中?

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?

银河中√捞星星 2024-07-13 16:19:51

对于每个因

  • 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))
东走西顾 2024-07-13 16:19:51

只需尝试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)
残花月 2024-07-13 16:19:51

虽然有很多好的答案,但这里有一个 1-liner 可以给出属性以及值:

(str(vars(config)).split(",")[1:])

其中“config”是有问题的对象。 我将其列为一个单独的答案,因为我只想简单地打印对象的相关值(不包括 __main 等),而不使用循环或漂亮的打印,并且没有找到方便的答案。

While there are many good answers, here is a 1-liner that can give the attributes AS WELL AS values:

(str(vars(config)).split(",")[1:])

where 'config' is the object in question. I am listing this as a separate answer because I just wanted to simply print the relevant values of the object (excl the __main etc) without using loops or pretty print and didn't find a convenient answer.

岛歌少女 2024-07-13 16:19:51

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.

笑咖 2024-07-13 16:19:51

该项目修改 pprint 以显示所有对象字段值,它忽略对象 __repr__ 成员函数,它还会递归到嵌套对象。 它适用于 python3,请参阅 https://github.com/MoserMichael/pprintex
您可以通过 pip 安装它:pip install printex

This project modifies pprint to show all object field values, it ignores he objects __repr__ member function, it also recurses into nested objects. It works with python3, see https://github.com/MoserMichael/pprintex
You can install it via pip: pip install printex

↙厌世 2024-07-13 16:19:51

vars() 似乎显示了该对象的属性,但 dir() 似乎也显示了父类的属性。 您通常不需要查看继承的属性,例如 strdoc字典

In [1]: class Aaa():
...:     def __init__(self, name, age):
...:         self.name = name
...:         self.age = age
...:
In [2]: class Bbb(Aaa):
...:     def __init__(self, name, age, job):
...:         super().__init__(name, age)
...:         self.job = job
...:
In [3]: a = Aaa('Pullayya',42)

In [4]: b = Bbb('Yellayya',41,'Cop')

In [5]: vars(a)
Out[5]: {'name': 'Pullayya', 'age': 42}

In [6]: vars(b)
Out[6]: {'name': 'Yellayya', 'age': 41, 'job': 'Cop'}

In [7]: dir(a)
Out[7]:
['__class__',
 '__delattr__',
 '__dict__',
 '__dir__',
 '__doc__',
 '__eq__',
 ...
 ...
 '__subclasshook__',
 '__weakref__',
 'age',
 'name']

vars() seems to show the attributes of this object, but dir() seems to show attributes of parent class(es) as well. You don't usually need to see inherited attributes such as str, doc. dict etc.

In [1]: class Aaa():
...:     def __init__(self, name, age):
...:         self.name = name
...:         self.age = age
...:
In [2]: class Bbb(Aaa):
...:     def __init__(self, name, age, job):
...:         super().__init__(name, age)
...:         self.job = job
...:
In [3]: a = Aaa('Pullayya',42)

In [4]: b = Bbb('Yellayya',41,'Cop')

In [5]: vars(a)
Out[5]: {'name': 'Pullayya', 'age': 42}

In [6]: vars(b)
Out[6]: {'name': 'Yellayya', 'age': 41, 'job': 'Cop'}

In [7]: dir(a)
Out[7]:
['__class__',
 '__delattr__',
 '__dict__',
 '__dir__',
 '__doc__',
 '__eq__',
 ...
 ...
 '__subclasshook__',
 '__weakref__',
 'age',
 'name']
我一直都在从未离去 2024-07-13 16:19:51

@dataclass + pprint(递归、缩进、无外部库、Python 3.10)

@dataclass 太棒了,Python 3.10 中的 pprint 学会了打印数据类带有缩进,因此如果您可以将代码转换为 @dataclass 这是一个非常好的方法:

from dataclasses import dataclass
from pprint import pprint

@dataclass
class MyClass1:
    s: str
    n0: int
    n1: int
    n2: int
    n3: int
    n4: int
    n5: int
    n6: int
    n7: int
    n8: int
    n9: int

@dataclass
class MyClass2:
    s: str
    n0: int
    n1: int
    n2: int
    n3: int
    n4: int
    n5: int
    n6: int
    n7: int
    n8: int
    n9: int
    my_class_1: MyClass1

obj = MyClass2(s='a', n0=0, n1=1, n2=2, n3=3, n4=4, n5=5, n6=6, n7=7, n8=8, n9=9, my_class_1=MyClass1(s='a', n0=0, n1=1, n2=2, n3=3, n4=4, n5=5, n6=6, n7=7, n8=8, n9=9))
print(obj)
pprint(obj)

输出:

MyClass2(s='a', n0=0, n1=1, n2=2, n3=3, n4=4, n5=5, n6=6, n7=7, n8=8, n9=9, my_class_1=MyClass1(s='a', n0=0, n1=1, n2=2, n3=3, n4=4, n5=5, n6=6, n7=7, n8=8, n9=9))
MyClass2(s='a',
         n0=0,
         n1=1,
         n2=2,
         n3=3,
         n4=4,
         n5=5,
         n6=6,
         n7=7,
         n8=8,
         n9=9,
         my_class_1=MyClass1(s='a',
                             n0=0,
                             n1=1,
                             n2=2,
                             n3=3,
                             n4=4,
                             n5=5,
                             n6=6,
                             n7=7,
                             n8=8,
                             n9=9))

另请参阅:带有换行符和缩进的漂亮打印数据类更漂亮

@dataclass 还免费为您提供其他非常好的功能:

与其他答案

让我们创建一个类似的非@dataclass代码

from pprint import pprint

class MyClass1:
    def __init__(self, s, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9):
        self.s = s
        self.n0 = n0
        self.n1 = n1
        self.n2 = n2
        self.n3 = n3
        self.n4 = n4
        self.n5 = n5
        self.n6 = n6
        self.n7 = n7
        self.n8 = n8
        self.n9 = n9

class MyClass2:
    def __init__(self, s, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, my_class_1):
        self.s = s
        self.n0 = n0
        self.n1 = n1
        self.n2 = n2
        self.n3 = n3
        self.n4 = n4
        self.n5 = n5
        self.n6 = n6
        self.n7 = n7
        self.n8 = n8
        self.n9 = n9
        self.n9 = n9
        self.my_class_1 = my_class_1

obj = MyClass2(s='a', n0=0, n1=1, n2=2, n3=3, n4=4, n5=5, n6=6, n7=7, n8=8, n9=9, my_class_1=MyClass1(s='a', n0=0, n1=1, n2=2, n3=3, n4=4, n5=5, n6=6, n7=7, n8=8, n9=9))
pprint(vars(obj))

pprint(vars(obj))输出是非递归:

{'my_class_1': <__main__.MyClass1 object at 0x7fee21a9bf70>,
 'n0': 0,
 'n1': 1,
 'n2': 2,
 'n3': 3,
 'n4': 4,
 'n5': 5,
 'n6': 6,
 'n7': 7,
 'n8': 8,
 'n9': 9,
 's': 'a'}

在 Python 3.10.7、Ubuntu 22.10 上测试。

@dataclass + pprint (recursive, indented, no external libs, Python 3.10)

@dataclass is just amazing, and pprint from Python 3.10 learnt to print dataclasses with indentation, so if you can convert your code to @dataclass this is a very good approach:

from dataclasses import dataclass
from pprint import pprint

@dataclass
class MyClass1:
    s: str
    n0: int
    n1: int
    n2: int
    n3: int
    n4: int
    n5: int
    n6: int
    n7: int
    n8: int
    n9: int

@dataclass
class MyClass2:
    s: str
    n0: int
    n1: int
    n2: int
    n3: int
    n4: int
    n5: int
    n6: int
    n7: int
    n8: int
    n9: int
    my_class_1: MyClass1

obj = MyClass2(s='a', n0=0, n1=1, n2=2, n3=3, n4=4, n5=5, n6=6, n7=7, n8=8, n9=9, my_class_1=MyClass1(s='a', n0=0, n1=1, n2=2, n3=3, n4=4, n5=5, n6=6, n7=7, n8=8, n9=9))
print(obj)
pprint(obj)

Output:

MyClass2(s='a', n0=0, n1=1, n2=2, n3=3, n4=4, n5=5, n6=6, n7=7, n8=8, n9=9, my_class_1=MyClass1(s='a', n0=0, n1=1, n2=2, n3=3, n4=4, n5=5, n6=6, n7=7, n8=8, n9=9))
MyClass2(s='a',
         n0=0,
         n1=1,
         n2=2,
         n3=3,
         n4=4,
         n5=5,
         n6=6,
         n7=7,
         n8=8,
         n9=9,
         my_class_1=MyClass1(s='a',
                             n0=0,
                             n1=1,
                             n2=2,
                             n3=3,
                             n4=4,
                             n5=5,
                             n6=6,
                             n7=7,
                             n8=8,
                             n9=9))

See also: Pretty-print dataclasses prettier with line breaks and indentation

@dataclass also gives you other very good features for free:

Vs other answers

Let's create a comparable non @dataclass code

from pprint import pprint

class MyClass1:
    def __init__(self, s, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9):
        self.s = s
        self.n0 = n0
        self.n1 = n1
        self.n2 = n2
        self.n3 = n3
        self.n4 = n4
        self.n5 = n5
        self.n6 = n6
        self.n7 = n7
        self.n8 = n8
        self.n9 = n9

class MyClass2:
    def __init__(self, s, n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, my_class_1):
        self.s = s
        self.n0 = n0
        self.n1 = n1
        self.n2 = n2
        self.n3 = n3
        self.n4 = n4
        self.n5 = n5
        self.n6 = n6
        self.n7 = n7
        self.n8 = n8
        self.n9 = n9
        self.n9 = n9
        self.my_class_1 = my_class_1

obj = MyClass2(s='a', n0=0, n1=1, n2=2, n3=3, n4=4, n5=5, n6=6, n7=7, n8=8, n9=9, my_class_1=MyClass1(s='a', n0=0, n1=1, n2=2, n3=3, n4=4, n5=5, n6=6, n7=7, n8=8, n9=9))
pprint(vars(obj))

pprint(vars(obj)) output is non-recursive:

{'my_class_1': <__main__.MyClass1 object at 0x7fee21a9bf70>,
 'n0': 0,
 'n1': 1,
 'n2': 2,
 'n3': 3,
 'n4': 4,
 'n5': 5,
 'n6': 6,
 'n7': 7,
 'n8': 8,
 'n9': 9,
 's': 'a'}

Tested on Python 3.10.7, Ubuntu 22.10.

最冷一天 2024-07-13 16:19:51

我想 var_dump / print_r Selenium 的浏览器状态,但它的一些类属性并不总是实现/可访问(取决于所使用的浏览器),这在某些情况下会导致异常。 到目前为止发布的解决方案似乎都无法解决该问题,因此我无法在崩溃之前转储所有属性。 这是我能想到的唯一干净的解决方案:

import warnings

def dump(obj):
  for name in dir(obj):
    e = False
    with warnings.catch_warnings():
      warnings.simplefilter("ignore")
      try:
        v = getattr(obj, name)
      except:
        e = True
      warnings.simplefilter("default")
    if not e:
      print("obj.%s = %r" % (name, v))
    else:
      print("<inaccessible property obj.%s>" % name)

这也可以抑制访问属性时的警告(例如弃用)。 请注意,它不是递归的。

I wanted to var_dump / print_r the browser state of Selenium, but some of its class properties are not always implemented / accessible (depending on the browser used), which causes exceptions in some cases. None of the solutions posted so far seemed to be able to work around that problem, so I was unable to dump all properties before things crashed. This is the only clean solution I could come up with:

import warnings

def dump(obj):
  for name in dir(obj):
    e = False
    with warnings.catch_warnings():
      warnings.simplefilter("ignore")
      try:
        v = getattr(obj, name)
      except:
        e = True
      warnings.simplefilter("default")
    if not e:
      print("obj.%s = %r" % (name, v))
    else:
      print("<inaccessible property obj.%s>" % name)

This also suppresses warnings (e.g. deprecations) upon accessing properties. Note that it is not recursive.

恏ㄋ傷疤忘ㄋ疼 2024-07-13 16:19:51

您可以尝试 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)
被你宠の有点坏 2024-07-13 16:19:51

答案中,可以稍微修改一下以仅获取对象的“属性”,如下所示:

def getAttributes(obj):
    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 for name in dir(obj) 
            if name[0] != '_' and name not in disallowed_names and hasattr(obj, name)}
    pprint(attributes(obj))

添加时很有帮助该函数是临时函数,无需对现有源代码进行太多更改即可删除

From the answer, it can be slightly modified to get only 'Attributes' of an object as below:

def getAttributes(obj):
    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 for name in dir(obj) 
            if name[0] != '_' and name not in disallowed_names and hasattr(obj, name)}
    pprint(attributes(obj))

It is helpful when adding this function temporary and can be removed without many changes in existing source code

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文