如何查看Python对象的内部?

374

我开始在各种项目中使用Python进行编程(包括Django Web开发和Panda3D游戏开发)。

为了帮助我理解正在发生的事情,我想基本上“查看”Python对象以查看它们的工作方式 - 如其方法和属性。

所以说,如果我有一个Python对象,我需要什么才能打印出它的内容?这可能吗?

28个回答

426

36
不知道这个术语叫做“内省”。这非常有帮助!还有你给我的所有功能...谢谢! - littlejim84
3
property、classmethod和staticmethod与内省无关。这些方法都创建了特殊类型的对象,可以用来定义具有特殊行为的类,但对于检查这些类或结构没有帮助。 - SingleNegationElimination
下面@Brian的回答向您展示了如何在Python中查看各种Python对象的源代码。这正是我最初搜索的内容,我相信我不会是唯一一个需要这个的人。(在这个回答中包含对他的回答的引用可能是值得的,因为它是最被接受的。) - michaelavila
这就像是 Python 内置的“智能感知”,我很喜欢。 - Bruno Bieri
10
我认为这是一个糟糕的答案。它没有给我们解决方案,只是在文档中提供了与此相关的所有内容。 - Ishan Srivastava
1
@IshanSrivastava 是正确的。你不应该提供答案链接,而应该提供答案。 - John Smith

228

object.__dict__


35
vars(object) 是为此而设计的。 - liberforce
20
实际上,“from pprint import pprint; pprint(vars(object))”给了我一个非常清晰的展示对象内容的视图。感谢@liberforce。 - N. Maks
查看对象及其内容的最佳方法是将其转换为字符串。 - Peter Krauss
这是一个很好的方法,可以查看实现任何表示方法的对象,或者像googleapiclient.errors.HttpError这样的对象,当你打印它们时,它们会打印不足够的信息,感谢@mtasic85。 - Felipe Valdes
简洁的星级响应 - M__

90

我很惊讶还没有人提到帮助呢!

In [1]: def foo():
   ...:     "foo!"
   ...:

In [2]: help(foo)
Help on function foo in module __main__:

foo()
    foo!

通过 Help 命令,您可以阅读文档字符串并了解类可能具有的属性,这非常有帮助。


然后您可以使用此处提到的其他技术。但是如果有docstring可用,请将其视为标准。 - Edward Falk
1
我不确定Python在过去几年中是否更新了这个函数,但是“help(object_name)”以高度结构化的格式提供了完整的概述。它是一个值得保留的工具。谢谢。 - Brian Cugelman

67

首先,阅读源代码。

其次,使用 dir() 函数。


5
这个来源比dir()更具信息量,培养这种习惯更好。 - S.Lott
16
我不太认同。dir()函数更快且在99%的情况下与help()联合使用可以让你找到所需的内容。 - bayer
7
我同意usuallyuseless的观点。很多时候,简单地调用dir()函数就足够了,从而避免你必须查阅源代码的麻烦。 - Sasha Chedygov
3
有时候运行时检查对象是有用的,但读取源代码则没有。例如,httplib.py类及其方法 :). - Denis Barmenkov
警告:在我从事网络开发的25年中,Python源代码是我见过的最糟糕的之一。当源代码是经过有意识的实践和原则构建,并且具备专业设计时,“阅读源代码”是有帮助的。但这在Python包中很少见。 - undefined

31
如果您想探索正在发生的事情,我建议看一下IPython。这将添加各种快捷方式,以获取对象的文档、属性甚至源代码。例如,在函数后面添加“?”将给出对象的帮助信息(实际上是“help(obj)”的快捷方式),而使用两个问号(“func??”)将显示源代码(如果有的话)。此外还有很多其他便利功能,如制表符补全、结果的漂亮打印、结果历史记录等,使其非常适用于这种探索性编程。
对于更多程序化的内省使用,基本内置函数比如dir()vars()getattr等会很有用,但检查inspect模块也值得花费时间。要获取函数的源代码,请使用“inspect.getsource”,例如将其应用于自身。
>>> print inspect.getsource(inspect.getsource)
def getsource(object):
    """Return the text of the source code for an object.

    The argument may be a module, class, method, function, traceback, frame,
    or code object.  The source code is returned as a single string.  An
    IOError is raised if the source code cannot be retrieved."""
    lines, lnum = getsourcelines(object)
    return string.join(lines, '')

inspect.getargspec在处理包装或操作函数时也经常很有用,因为它会给出函数参数的名称和默认值。


27
如果您对此想要一个GUI界面,可以查看objbrowser。它在对象内省方面使用了Python标准库中的inspect模块。 objbrowserscreenshot

13

试试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(), indent='    ', depth=2, width=30, seq_length=6,
              show_protected=True, show_private=False, show_static=True,
              show_properties=True, show_address=True)

输出:

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

12

虽然其他人已经提到了pprint,但我想补充一些背景信息。

pprint模块提供了一种能够以可用作解释器输入的形式“漂亮打印”任意Python数据结构的功能。如果格式化的结构包括不是基本Python类型的对象,则表示可能无法加载。如果包括文件、套接字、类或实例等对象,以及许多其他无法表示为Python常量的内置对象,就可能出现这种情况。

pprint可能会受到具有PHP背景的开发人员的高度需求,他们正在寻找var_dump()的替代方法。

具有字典属性的对象可以使用pprint()vars()混合转储,后者返回模块、类、实例等的__dict__属性:

from pprint import pprint
pprint(vars(your_object))

因此,无需循环

要转储包含在全局本地作用域中的所有变量,只需使用:

pprint(globals())
pprint(locals())

locals() 函数显示在函数内定义的变量。
此外,使用相应名称作为字符串键访问函数也很有用,以及其他用途

locals()['foo']() # foo()
globals()['foo']() # foo()

同样地,使用dir()可以查看模块的内容或对象的属性。
还有更多。

我试图学习opencv中的匹配结构,但是没有成功。

python3 orb.py

Traceback (most recent call last): File "orb.py", line 47, in <module> pprint( matches[0]) TypeError: 'module' object is not callable print(matches[0]) <DMatch 0x7f7e8b5270>

python3 orb.py

Traceback (most recent call last): File "orb.py", line 48, in <module> pprint( vars(matches[0])) TypeError: vars()参数必须具有__dict__属性。
- nerkn

12

你可以在shell中使用dir()列出对象的属性:

>>> dir(object())
['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']

当然,还有inspect模块:http://docs.python.org/library/inspect.html#module-inspect


9

有一款非常酷的工具叫做objexplore。以下是一个简单的示例,演示如何在pandas DataFrame上使用它的explore函数。

import pandas as pd
df=pd.read_csv('https://storage.googleapis.com/download.tensorflow.org/data/heart.csv')

from objexplore import explore
explore(df)

在您的shell中将弹出以下内容:

输入图像描述

2
真的很酷很有用!有没有办法在Jupyter笔记本中与它进行交互? - Vovin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接