如何查看Python对象内部?

如何查看Python对象内部?,python,introspection,Python,Introspection,我开始使用Python编写各种项目的代码(包括Django web开发和Panda3D游戏开发) 为了帮助我理解发生了什么,我想基本上“查看”Python对象内部,看看它们是如何勾选的——就像它们的方法和属性一样 假设我有一个Python对象,我需要什么来打印它的内容?这可能吗?首先,阅读源代码 其次,使用dir()函数。您可以在shell中使用dir()列出对象的属性: >>> dir(object()) ['__class__', '__delattr__', '__doc

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

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


假设我有一个Python对象,我需要什么来打印它的内容?这可能吗?

首先,阅读源代码


其次,使用
dir()
函数。

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

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

当然,还有inspect模块:

Python有一套强大的内省功能

请看以下内容:


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

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

如果您想查看参数和方法,可以将pprint和dir一起使用,正如其他人指出的,您可以使用
pprint
dir()

如果您想查看内容的实际值,可以这样做


object.\uuuu dict\uuuuu
如果这是为了探索到底发生了什么,我建议你看看。这会添加各种快捷方式来获取对象文档、属性甚至源代码。例如,在函数中添加“?”将为对象提供帮助(实际上是“帮助(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
在处理包装或操作函数时也很有用,因为它会给出函数参数的名称和默认值。

对象。

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

>>> import string
>>> string.__file__
'/usr/lib/python2.5/string.pyc'
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())
已编译*.pyc文件,因此请删除尾随的“c”,并在您喜爱的编辑器或文件查看器中打开未编译的*.py文件:

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

我发现这对于发现从给定API引发的异常非常有用。在Python世界中,这种详细信息很少得到很好的记录。

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

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

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

foo()
    foo!

“帮助”可以让您阅读docstring并了解类可能具有的属性,这非常有用。

如果您想查看活动对象的内部,那么python的
inspect
模块是一个很好的答案。通常,它可以用于获取在磁盘上某个位置的源文件中定义的函数的源代码nt要获取解释器中定义的活动函数和lambda的源代码,您可以使用
dill.source.getsource
from。它还可以获取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

>>> 

有一个python代码库构建就是为了这个目的:在Python2.7中引入,如果您对GUI感兴趣,请看一看。它使用python标准库中的inspect模块进行下面的对象内省

试试看

输出:

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

检查代码的两个重要工具是:

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

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

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

    import pprint
    
    pprint.pprint(obj.__dict__)
    

    虽然其他人已经提到过,但我想添加一些上下文

    pprint模块提供了“精确打印”任意内容的功能 Python数据结构,其形式可以用作 如果格式化的结构包含的对象不是 基本Python类型,表示可能无法加载 如果对象(如文件、套接字、类或 包括实例以及许多其他内置对象 不能表示为Python常量

    pprint
    对于具有PHP背景的开发人员来说,可能有很高的需求,他们正在寻找替代方案

    使用
    pprint()
    mixed with可以很好地转储具有dict属性的对象,该方法返回模块、类、实例等的
    \uuuu dict\uuu
    属性:

    from pprint import pprint
    pprint(vars(your_object))
    
    所以

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

    pprint(globals())
    pprint(locals())
    
    locals()
    显示函数中定义的变量。
    在以下情况下,使用相应名称作为字符串键访问函数也很有用:

    类似地,使用查看模块的内容或对象的属性

    import pprint
    
    pprint.pprint(obj.__dict__)
    
    还有更多。

    尝试使用:

    print(object.stringify())
    
    • 其中,
      object
      是您要创建的对象的变量名
      locals()['foo']() # foo()
      globals()['foo']() # foo()
      
      print(object.stringify())
      
      object?
      
      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"}
      
      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
        >
      >