是否有一个内置函数可以打印对象的所有当前属性和值?
所以我在这里寻找的是类似 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(30)
您希望将
vars()
与pprint()
混合:You want
vars()
mixed withpprint()
:你实际上是在把两种不同的东西混合在一起。
使用
dir()
,vars()
或inspect
模块来获取您感兴趣的内容(我使用__builtins__
作为示例;您可以使用任何对象代替)。无论你喜欢什么,都可以打印该字典:
或者
在交互式调试器中也可以使用漂亮的打印作为命令:
You are really mixing together two different things.
Use
dir()
,vars()
or theinspect
module to get what you are interested in (I use__builtins__
as an example; you can use any object instead).Print that dictionary however fancy you like:
or
Pretty printing is also available in the interactive debugger as a command:
有许多第三方函数可以根据作者的喜好添加异常处理、国家/特殊字符打印、递归到嵌套对象等功能。 但它们基本上都归结为这一点。
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.
已经提到了
dir
,但这只会为您提供属性的名称。 如果您也想要它们的值,请尝试__dict__
。这是输出:
dir
has been mentioned, but that'll only give you the attributes' names. If you want their values as well, try__dict__
.Here is the output:
否。获得最多支持的答案排除了某些类型的属性,而接受的答案显示了如何获取所有属性,包括方法和非公共 api 的部分。 但是没有一个好的完整的内置功能来实现这一点。
因此,简短的推论是,您可以编写自己的,但它将计算属于公共 API 一部分的属性和其他计算数据描述符,您可能不希望这样:
其他答案的问题
观察当前投票最高的应用程序在具有许多不同类型数据成员的类上回答:
仅打印:
因为
vars
only 返回对象的__dict__
,并且它是不是副本,因此如果您修改 vars 返回的字典,您也会修改对象本身的 __dict__ 。返回:
--这很糟糕,因为 quux 是一个我们不应该设置的属性,也不应该位于命名空间中...
在当前接受的答案(和其他答案)中应用建议并没有好多少:
正如我们可以的那样请注意,
dir
仅返回与对象关联的所有(实际上只是大多数)名称。评论中提到的
inspect.getmembers
也有类似的缺陷 - 它返回所有名称和值。在课堂上
教学时,我让学生创建一个提供对象的语义公共 API 的函数:
我们可以扩展它以提供对象的语义命名空间的副本,但我们需要排除< code>__slots__ 未分配,如果我们认真对待“当前属性”的请求,我们需要排除计算属性(因为它们可能会变得昂贵,并且可能被解释为不是“当前”) ):
现在我们不计算或显示财产,quux:
警告
但也许我们确实知道我们的财产并不昂贵。 我们可能想改变逻辑以将它们也包括在内。 也许我们想排除其他自定义数据描述符。
那么我们就需要进一步定制这个功能。 因此,我们不能有一个内置函数能够神奇地准确地知道我们想要什么并提供它,这是有道理的。 这是我们需要自己创建的功能。
结论
没有内置函数可以执行此操作,您应该执行在语义上最适合您的情况的操作。
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:
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:
only prints:
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.returns:
-- 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:
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:
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"):And now we do not calculate or show the property, quux:
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.
您可以使用“dir()”函数来执行此操作。
另一个有用的功能是帮助。
You can use the "dir()" function to do this.
Another useful feature is help.
要打印对象的当前状态,您可以:
或
或
为您的类定义
__str__
或__repr__
方法。 来自 Python 文档:To print the current state of the object you might:
or
or
For your classes define
__str__
or__repr__
methods. From the Python documentation:我建议使用
help(your_object)
。帮助(目录)
帮助(变量)
I recommend using
help(your_object)
.help(dir)
help(vars)
可能值得一试 -
是否有与 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).
在大多数情况下,使用 __dict__ 或 dir() 将为您提供所需的信息。 如果您碰巧需要更多详细信息,标准库包含 inspect 模块,这可以让你获得一些令人印象深刻的细节。 一些真正有价值的信息包括:
如果您只是在寻找“我的对象有什么属性值” ?”,那么
dir()
和__dict__
可能就足够了。 如果您真的想深入了解任意对象的当前状态(请记住,在 python 中几乎所有东西都是对象),那么inspect
值得考虑。In most cases, using
__dict__
ordir()
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: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), theninspect
is worthy of consideration.如果您使用它进行调试,并且您只想对所有内容进行递归转储,则接受的答案并不令人满意,因为它要求您的类已经具有良好的
__str__
实现。 如果情况并非如此,则效果会更好: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:尝试 ppretty
输出:
Try ppretty
Output:
元编程示例 神奇转储对象:
不带参数:
带 < a href="http://www.gnosis.cx/download/Gnosis_Utils.More/" rel="noreferrer">Gnosis Utils:
它有点过时,但仍然有效。
A metaprogramming example Dump object with magic:
Without arguments:
With Gnosis Utils:
It is a bit outdated but still working.
这会以 json 或 yaml 缩进格式递归打印出所有对象内容:
This prints out all the object contents recursively in json or yaml indented format:
为什么不做一些简单的事情:
Why not something simple:
无论变量在类中、 __init__ 内部或外部如何定义,这都有效。
This works no matter how your varibles are defined within a class, inside __init__ or outside.
如果您想查看复杂数据结构中的所有值,请执行以下操作:
其中 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:
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 usingvars()
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.
我需要在某些日志中打印调试信息,但无法使用 pprint,因为它会破坏它。 相反,我这样做并得到了几乎相同的结果。
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.
要转储“myObject”:
我尝试了 vars() 和 dir(); 两者都未能满足我的要求。 vars() 不起作用,因为该对象没有 __dict__ (exceptions.TypeError:vars() 参数必须具有 __dict__ 属性)。 dir() 不是我想要的:它只是字段名称的列表,没有给出值或对象结构。
我认为 json.dumps() 适用于大多数没有 default=json_util.default 的对象,但我在对象中有一个日期时间字段,因此标准 json 序列化器失败了。 请参阅 如何克服“datetime.datetime 不可 JSON 序列化”在Python中?
To dump "myObject":
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?
对于每个因
vars()
不返回所有属性而苦苦挣扎的人。dir()
不返回属性的值。以下代码打印
obj
的所有属性及其值: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:只需尝试beeprint。
它不仅可以帮助您打印对象变量,还可以帮助您打印漂亮的输出,如下所示:
Just try beeprint.
It will help you not only with printing object variables, but beautiful output as well, like this:
虽然有很多好的答案,但这里有一个 1-liner 可以给出属性以及值:
其中“config”是有问题的对象。 我将其列为一个单独的答案,因为我只想简单地打印对象的相关值(不包括 __main 等),而不使用循环或漂亮的打印,并且没有找到方便的答案。
While there are many good answers, here is a 1-liner that can give the attributes AS WELL AS values:
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.
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.
该项目修改 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/pprintexYou can install it via pip:
pip install printex
vars() 似乎显示了该对象的属性,但 dir() 似乎也显示了父类的属性。 您通常不需要查看继承的属性,例如 str、doc。 字典等
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.
@dataclass
+pprint
(递归、缩进、无外部库、Python 3.10)@dataclass
太棒了,Python 3.10 中的pprint
学会了打印数据类带有缩进,因此如果您可以将代码转换为@dataclass
这是一个非常好的方法:输出:
另请参阅:带有换行符和缩进的漂亮打印数据类更漂亮
@dataclass
还免费为您提供其他非常好的功能:__hash__
和__eq__
: 自定义类型的对象为字典键__slots__
:阻止在 __init__ 之外创建新属性与其他答案
让我们创建一个类似的非
@dataclass
代码pprint(vars(obj))
输出是非递归:在 Python 3.10.7、Ubuntu 22.10 上测试。
@dataclass
+pprint
(recursive, indented, no external libs, Python 3.10)@dataclass
is just amazing, andpprint
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:Output:
See also: Pretty-print dataclasses prettier with line breaks and indentation
@dataclass
also gives you other very good features for free:__hash__
and__eq__
: Object of custom type as dictionary key__slots__
: Prevent creating new attributes outside __init__Vs other answers
Let's create a comparable non
@dataclass
codepprint(vars(obj))
output is non-recursive:Tested on Python 3.10.7, Ubuntu 22.10.
我想 var_dump / print_r Selenium 的浏览器状态,但它的一些类属性并不总是实现/可访问(取决于所使用的浏览器),这在某些情况下会导致异常。 到目前为止发布的解决方案似乎都无法解决该问题,因此我无法在崩溃之前转储所有属性。 这是我能想到的唯一干净的解决方案:
这也可以抑制访问属性时的警告(例如弃用)。 请注意,它不是递归的。
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:
This also suppresses warnings (e.g. deprecations) upon accessing properties. Note that it is not recursive.
您可以尝试 Flask 调试工具栏。
https://pypi.python.org/pypi/Flask-DebugToolbar
You can try the Flask Debug Toolbar.
https://pypi.python.org/pypi/Flask-DebugToolbar
从答案中,可以稍微修改一下以仅获取对象的“属性”,如下所示:
添加时很有帮助该函数是临时函数,无需对现有源代码进行太多更改即可删除
From the answer, it can be slightly modified to get only 'Attributes' of an object as below:
It is helpful when adding this function temporary and can be removed without many changes in existing source code