我如何看待Python对象内部?

问题:我如何看待Python对象内部?

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

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

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

I’m starting to code in various projects using Python (including Django web development and Panda3D game development).

To help me understand what’s going on, I would like to basically ‘look’ inside the Python objects to see how they tick – like their methods and properties.

So say I have a Python object, what would I need to print out its contents? Is that even possible?


回答 0

Python具有强大的自省功能。

看一下以下内置函数

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

Python has a strong set of introspection features.

Take a look at the following built-in functions:

type() and dir() are particularly useful for inspecting the type of an object and its set of attributes, respectively.


回答 1

object.__dict__

object.__dict__


回答 2

首先,阅读源代码。

其次,使用dir()功能。

First, read the source.

Second, use the dir() function.


回答 3

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

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

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

foo()
    foo!

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

I’m surprised no one’s mentioned help yet!

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

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

foo()
    foo!

Help lets you read the docstring and get an idea of what attributes a class might have, which is pretty helpful.


回答 4

如果这是为了探索发生了什么而进行的探索,建议您查看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 如果要处理包装或操纵函数,它通常也很有用,因为它将提供函数参数的名称和默认值。

If this is for exploration to see what’s going on, I’d recommend looking at IPython. This adds various shortcuts to obtain an objects documentation, properties and even source code. For instance appending a “?” to a function will give the help for the object (effectively a shortcut for “help(obj)”, wheras using two ?’s (“func??“) will display the sourcecode if it is available.

There are also a lot of additional conveniences, like tab completion, pretty printing of results, result history etc. that make it very handy for this sort of exploratory programming.

For more programmatic use of introspection, the basic builtins like dir(), vars(), getattr etc will be useful, but it is well worth your time to check out the inspect module. To fetch the source of a function, use “inspect.getsource” eg, applying it to itself:

>>> 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 is also frequently useful if you’re dealing with wrapping or manipulating functions, as it will give the names and default values of function parameters.


回答 5

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

If you’re interested in a GUI for this, take a look at objbrowser. It uses the inspect module from the Python standard library for the object introspection underneath.


回答 6

您可以在外壳程序中使用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

You can list the attributes of a object with dir() in the shell:

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

Of course, there is also the inspect module: http://docs.python.org/library/inspect.html#module-inspect


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

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

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

Output:

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

回答 9

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

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

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

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

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

Others have already mentioned the dir() built-in which sounds like what you’re looking for, but here’s another good tip. Many libraries — including most of the standard library — are distributed in source form. Meaning you can pretty easily read the source code directly. The trick is in finding it; for example:

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

The *.pyc file is compiled, so remove the trailing ‘c’ and open up the uncompiled *.py file in your favorite editor or file viewer:

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

I’ve found this incredibly useful for discovering things like which exceptions are raised from a given API. This kind of detail is rarely well-documented in the Python world.


回答 10

尽管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()用于查看模块的内容或对象的属性。

还有更多。

While pprint has been mentioned already by others I’d like to add some context.

The pprint module provides a capability to “pretty-print” arbitrary Python data structures in a form which can be used as input to the interpreter. If the formatted structures include objects which are not fundamental Python types, the representation may not be loadable. This may be the case if objects such as files, sockets, classes, or instances are included, as well as many other built-in objects which are not representable as Python constants.

pprint might be in high-demand by developers with a PHP background who are looking for an alternative to var_dump().

Objects with a dict attribute can be dumped nicely using pprint() mixed with vars(), which returns the __dict__ attribute for a module, class, instance, etc.:

from pprint import pprint
pprint(vars(your_object))

So, no need for a loop.

To dump all variables contained in the global or local scope simply use:

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

locals() shows variables defined in a function.
It’s also useful to access functions with their corresponding name as a string key, among other usages:

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

Similarly, using dir() to see the contents of a module, or the attributes of an object.

And there is still more.


回答 11

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

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

object.__dict__

If you want to look at parameters and methods, as others have pointed out you may well use pprint or dir()

If you want to see the actual value of the contents, you can do

object.__dict__


回答 12

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

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

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

Two great tools for inspecting code are:

  1. IPython. A python terminal that allows you to inspect using tab completion.

  2. Eclipse with the PyDev plugin. It has an excellent debugger that allows you to break at a given spot and inspect objects by browsing all variables as a tree. You can even use the embedded terminal to try code at that spot or type the object and press ‘.’ to have it give code hints for you.


回答 13

pprint和dir一起工作很好

pprint and dir together work great


回答 14

有一个专门用于此目的的python代码库构建:inspect Python 2.7中引入

There is a python code library build just for this purpose: inspect Introduced in Python 2.7


回答 15

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

myobj??

If you are interested to see the source code of the function corresponding to the object myobj, you can type in iPython or Jupyter Notebook:

myobj??


回答 16

import pprint

pprint.pprint(obj.__dict__)

要么

pprint.pprint(vars(obj))
import pprint

pprint.pprint(obj.__dict__)

or

pprint.pprint(vars(obj))

回答 17

如果要查看活动对象内部,则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

>>> 

If you want to look inside a live object, then python’s inspect module is a good answer. In general, it works for getting the source code of functions that are defined in a source file somewhere on disk. If you want to get the source of live functions and lambdas that were defined in the interpreter, you can use dill.source.getsource from dill. It also can get the code for from bound or unbound class methods and functions defined in curries… however, you might not be able to compile that code without the enclosing object’s code.

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

>>> 

回答 18

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

vars(obj) returns the attributes of an object.


回答 19

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

In addition if you want to look inside list and dictionaries, you can use pprint()


回答 20

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

object?

Many good tipps already, but the shortest and easiest (not necessarily the best) has yet to be mentioned:

object?

回答 21

尝试使用:

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

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

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

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

  • dir(object())

要么

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

Try using:

print(object.stringify())
  • where object is the variable name of the object you are trying to inspect.

This prints out a nicely formatted and tabbed output showing all the hierarchy of keys and values in the object.

NOTE: This works in python3. Not sure if it works in earlier versions

UPDATE: This doesn’t work on all types of objects. If you encounter one of those types (like a Request object), use one of the following instead:

  • dir(object())

or

import pprint then: pprint.pprint(object.__dict__)