我如何看待Python对象内部?


291

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

为了帮助我理解发生了什么,我想基本上在Python对象内部“看”看它们如何打勾-像它们的方法和属性一样。

假设我有一个Python对象,我需要打印出什么内容?那有可能吗?

Answers:


352

Python具有强大的自省功能。

看一下以下内置函数

type()并且dir()是用于检查物体的类型和,分别其属性集的特别有用的。


25
不知道这个词是“内省”。那是很大的帮助!以及您给我的所有功能...谢谢!
littlejim84

2
属性,类方法和静态方法与自省无关。这些方法都会创建特殊类型的对象,这些对象可用于定义具有特殊行为的类,但对检查这些类或构造没有帮助。
SingleNegationElimination

下面来自@Brian的答案显示了如何从python中查看各种python对象的源代码。那就是我最初寻找的东西,我确定我不会孤单。(由于它是最被接受的,因此可能值得在此答案中提及他的答案。)
michaelavila 2012年

就像内置于python的“ IntelliSense”一样。我喜欢它。
布鲁诺·比耶里

7
我认为这是一个错误的答案。除了提供解决方案外,它还提供了与文档中的内容相关的一切
Ishan Srivastava

176

object.__dict__


12
vars(object)为此。
liberforce

6
实际上from pprint import pprint; pprint(vars(object)),我对对象的内容有了很好的了解。感谢@liberforce
N. Maks

查看字符串中的对象及其内容的最佳方法
Peter Krauss

这是查看实现任何表示方法的对象或googleapiclient.errors.HttpError之类的对象的好方法,当您打印它们时,它们肯定会打印出不足的信息,谢谢@ mtasic85
Felipe Valdes

65

首先,阅读源代码。

其次,使用dir()功能。


92
我把那个顺序颠倒了。
拜耳

5
该源代码比dir()提供更多信息,并具有更好的养成习惯。
S.Lott

14
我不敢苟同。dir()的速度要快得多,在99%的情况下,让您结合使用help()可以找到所需的内容。
拜耳2009年

7
我同意通常没用。在许多情况下,对dir()的简单调用就足够了,从而为您省去了查看源代码的麻烦。
Sasha Chedygov,2009年

3
有时在运行时检查对象可能很有用,但读取源却没有用。例如httplib.py类及其方法:)。
Denis Barmenkov 2012年

61

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

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

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

foo()
    foo!

帮助可让您阅读文档字符串并了解类可能具有的属性,这非常有帮助。


然后,您将使用此处提到的其他技术。但是,如果文档字符串可用,请考虑使用佳能。
爱德华·福尔克

我不确定python是否在最近几年中更新了此功能,但是“ help(object_name)”以高度结构化的格式提供了完整的概述。是老板 谢谢。
Brian Cugelman

27

如果这是为了探索发生了什么而进行的探索,建议您查看IPython。这添加了各种快捷方式来获取对象文档,属性甚至源代码。例如附加一个“?” 函数将提供对象的帮助(实际上是“ help(obj)”的快捷方式,使用两个?的快捷方式(“ func??”)将显示源代码(如果可用)。

还有很多其他的便利,例如制表符完成,漂亮的结果打印,结果历史记录等,这使得这种探索性编程非常方便。

欲了解更多程序中使用内省的,基本建宏喜欢dir()vars()getattr等将是有益的,但它是值得你花时间检查出的检查模块。要获取函数的来源,请使用“ 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 如果要处理包装或操纵函数,它通常也很有用,因为它将提供函数参数的名称和默认值。


17

如果您对此GUI感兴趣,请查看objbrowser。它使用Python标准库中的inspect模块对下面的对象进行自省。

objbrowser截屏


9

您可以在外壳程序中使用dir()列出对象的属性:

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

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


8
"""Visit http://diveintopython.net/"""

__author__ = "Mark Pilgrim (mark@diveintopython.org)"


def info(object, spacing=10, collapse=1):
    """Print methods and doc strings.

    Takes module, class, list, dictionary, or string."""
    methodList = [e for e in dir(object) if callable(getattr(object, e))]
    processFunc = collapse and (lambda s: " ".join(s.split())) or (lambda s: s)
    print "\n".join(["%s %s" %
                     (method.ljust(spacing),
                      processFunc(str(getattr(object, method).__doc__)))
                     for method in methodList])

if __name__ == "__main__":
    print help.__doc__

4
如果仅在打印件周围添加括号,则在python 3中效果很好。
ConstantineK

8

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

7

其他人已经提到了dir()内置函数,听起来像您要找的东西,但这是另一个好技巧。许多库(包括大多数标准库)都以源代码形式分发。这意味着您可以轻松地直接阅读源代码。诀窍在于找到它;例如:

>>> import string
>>> string.__file__
'/usr/lib/python2.5/string.pyc'

* .pyc文件已编译,因此请删除结尾的“ c”并在您喜欢的编辑器或文件查看器中打开未编译的* .py文件:

/usr/lib/python2.5/string.py

我发现这对于发现诸如从给定API引发哪些异常之类的事情非常有用。这种细节很少在Python世界中有充分的文献记载。


7

尽管pprint其他人已经提到过,但我想添加一些上下文。

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

pprint 寻找PHP替代方案的具有PHP背景的开发人员可能需求很高 var_dump()

带有dict属性的对象可以很好地pprint()与混合使用来转储vars(),它返回__dict__模块,类,实例等的属性:

from pprint import pprint
pprint(vars(your_object))

因此,不需要循环

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

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

locals()显示函数中定义的变量。
这也是有用的与他们对应的名字作为一个字符串键,其中接入功能的其他用途

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

同样,dir()用于查看模块的内容或对象的属性。

还有更多。



4

检查代码的两个很棒的工具是:

  1. IPython。允许您使用制表符完成功能进行检查的python终端。

  2. 带有PyDev插件的Eclipse。它具有出色的调试器,可让您在给定的位置中断并通过将所有变量浏览为树来检查对象。您甚至可以使用嵌入式终端在该位置尝试代码或键入对象,然后按“。”。让它为您提供代码提示。

在此处输入图片说明




3

如果您希望查看与该对象相对应的函数的源代码,则myobj可以输入iPythonJupyter Notebook

myobj??


2
import pprint

pprint.pprint(obj.__dict__)

要么

pprint.pprint(vars(obj))

尽管此代码可以回答问题,但提供有关如何和/或为什么解决问题的其他上下文将提高答案的长期价值。
亚历山大

1

如果要查看活动对象内部,则python的inspect模块是一个很好的答案。通常,它用于获取在磁盘上某处的源文件中定义的功能的源代码。如果要获取解释器中定义的实时函数和lambda的来源,则可以使用dill.source.getsourcefrom dill。它也可以从咖喱中定义的绑定或未绑定类方法和函数中获取代码。但是,如果没有封闭对象的代码,则可能无法编译该代码。

>>> from dill.source import getsource
>>> 
>>> def add(x,y):
...   return x+y
... 
>>> squared = lambda x:x**2
>>> 
>>> print getsource(add)
def add(x,y):
  return x+y

>>> print getsource(squared)
squared = lambda x:x**2

>>> 
>>> class Foo(object):
...   def bar(self, x):
...     return x*x+x
... 
>>> f = Foo()
>>> 
>>> print getsource(f.bar)
def bar(self, x):
    return x*x+x

>>> 


0

另外,如果您想查看列表和字典,则可以使用pprint()


0

已经有很多好的小费,但是最短和最简单的(不一定是最好的)尚未被提及:

object?

-3

尝试使用:

print(object.stringify())
  • object您要检查的对象的变量名在哪里。

这会打印出格式正确的选项卡式输出,显示对象中所有键和值的层次结构。

注意:这在python3中有效。不知道它是否可以在早期版本中使用

更新:这不适用于所有类型的对象。如果遇到这些类型之一(例如Request对象),请改用以下一种方法:

  • dir(object())

要么

import pprint 然后: pprint.pprint(object.__dict__)


1
在'Request'对象上不起作用“'Request'对象没有属性'stringify'”
AlxVallejo
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.