我如何查看Python对象?

时间:2009-06-17 10:17:19

标签: python introspection

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

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

所以说我有一个Python对象,我需要打印出它的内容?这甚至可能吗?

24 个答案:

答案 0 :(得分:291)

Python有一套强大的内省功能。

请查看以下built-in functions

type()dir()对于分别检查对象的类型及其属性集特别有用。

答案 1 :(得分:154)

object.__dict__

答案 2 :(得分:58)

首先,阅读来源。

其次,使用dir()函数。

答案 3 :(得分:50)

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

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

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

foo()
    foo!

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

答案 4 :(得分:26)

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

还有许多额外的便利,例如标签完成,结果的漂亮打印,结果历史记录等,这使得这种探索性编程非常方便。

对于内省的更多程序化使用,dir()vars()getattr等基本内置函数将非常有用,但值得您花些时间查看{{3模块。要获取函数的来源,请使用“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也经常有用,因为它会给出函数参数的名称和默认值。

答案 5 :(得分:14)

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

objbrowserscreenshot

答案 6 :(得分:7)

您可以在shell中列出具有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

答案 7 :(得分:7)

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

答案 8 :(得分:7)

其他人已经提到了内置的dir()听起来像你正在寻找的,但这是另一个好的提示。许多库 - 包括大多数标准库 - 以源代码形式分发。这意味着你可以很容易地直接读取源代码。诀窍是找到它;例如:

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

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

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

我发现这非常有用,可以发现从给定的API中引发异常的事情。 Python世界中很少详细记录这种细节。

答案 9 :(得分:7)

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

答案 10 :(得分:6)

虽然其他人已经提及pprint,但我想添加一些背景信息。

  

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

具有PHP背景的开发人员可能会高度要求

pprint,他们正在寻找var_dump()的替代方案。

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

from pprint import pprint
pprint(vars(your_object))

所以,no need for a loop

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

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

locals()显示函数中定义的变量 在other usages中访问具有相应名称作为字符串键的函数也很有用:

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

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

还有更多。

答案 11 :(得分:4)

如果您想查看参数和方法,正如其他人指出的那样,您可以使用pprintdir()

如果要查看内容的实际值,可以执行

object.__dict__

答案 12 :(得分:3)

为此目的有一个python代码库构建:inspect在Python 2.7中引入

答案 13 :(得分:3)

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

  1. IPython。一个python终端,允许您使用制表符完成检查。

  2. EclipsePyDev plugin。它有一个出色的调试器,允许您在给定的位置中断并通过将所有变量作为树浏览来检查对象。您甚至可以使用嵌入式终端在该位置尝试代码或键入对象并按“。”让它为你提供代码提示。

  3. enter image description here

答案 14 :(得分:2)

pprint和dir一起工作很棒

答案 15 :(得分:2)

在 Python 3.8 中,您可以使用 __dict__ 打印出对象的内容。例如,

class Person():
   pass

person = Person()

## set attributes
person.first = 'Oyinda'
person.last = 'David'

## to see the content of the object
print(person.__dict__)  

{"first": "Oyinda", "last": "David"}

答案 16 :(得分:1)

如果你想查看一个活的对象,那么python的inspect模块就是一个很好的答案。通常,它适用于获取磁盘上某处源文件中定义的函数的源代码。如果要获取解释器中定义的实时函数和lambda的来源,可以使用dill中的dill.source.getsource。它还可以从curries中定义的绑定或非绑定类方法和函数中获取代码...但是,如果没有封闭对象的代码,您可能无法编译该代码。

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

>>> 

答案 17 :(得分:1)

vars(obj)返回对象的属性。

答案 18 :(得分:1)

import pprint

pprint.pprint(obj.__dict__)

pprint.pprint(vars(obj))

答案 19 :(得分:1)

如果您有兴趣查看与对象myobj对应的函数的源代码,可以输入iPythonJupyter Notebook

myobj??

答案 20 :(得分:1)

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

object?

答案 21 :(得分:0)

此外,如果您想查看列表和词典,可以使用pprint()

答案 22 :(得分:0)

如果您正在寻找更微妙的解决方案,您可以尝试objprint。它的积极方面是它可以处理嵌套对象。例如:

from objprint import objprint

class Position:
    def __init__(self, x, y):
        self.x = x
        self.y = y

class Player:
    def __init__(self):
        self.name = "Alice"
        self.age = 18
        self.items = ["axe", "armor"]
        self.coins = {"gold": 1, "silver": 33, "bronze": 57}
        self.position = Position(3, 5)

objprint(Player())

会打印出来

<Player
  .name = 'Alice',
  .age = 18,
  .items = ['axe', 'armor'],
  .coins = {'gold': 1, 'silver': 33, 'bronze': 57},
  .position = <Position
    .x = 3,
    .y = 5
  >
>

答案 23 :(得分:-2)

尝试使用:

print(object.stringify())
  • 其中object是您要检查的对象的变量名称。

这将打印出格式良好且带标签的输出,显示对象中键和值的所有层次结构。

注意:这适用于python3。不确定它是否适用于早期版本