Как мне посмотреть внутри объекта Python?


291

Я начинаю программировать в различных проектах с использованием Python (включая веб-разработку Django и разработку игр Panda3D).

Чтобы помочь мне понять, что происходит, я бы хотел «заглянуть» внутрь объектов Python, чтобы увидеть, как они помечаются - как их методы и свойства.

Скажем, у меня есть объект Python, что мне нужно, чтобы распечатать его содержимое? Это вообще возможно?

Ответы:


352

Python обладает мощным набором функций для самоанализа.

Взгляните на следующие встроенные функции :

type()и dir()особенно полезны для проверки типа объекта и его набора атрибутов соответственно.


25
Не знал, что термин «самоанализ». Это отличная помощь! А также все функции, которые вы мне дали ... Спасибо!
littlejim84

2
свойство, метод класса и метод статики не связаны с самоанализом. Все эти методы создают специальные типы объектов, которые могут использоваться для определения классов со специальным поведением, но не помогают при проверке этих классов или конструкций.
SingleNegationElimination

Ответ от @Brian ниже показывает вам, как также просмотреть исходный код различных объектов Python из Python. Это то, что я искал изначально, и я уверен, что я не буду одинок. (Возможно, стоит включить ссылку на его ответ в этот ответ, поскольку он наиболее приемлем.)
michaelavila

Это как встроенный IntelliSense для Python. Я люблю это.
Бруно Биери

7
Я думаю, что это плохой ответ. вместо того, чтобы давать нам решение, оно просто дает нам все, что связано с этим в документации
Ишан Шривастава

176

object.__dict__


12
vars(object)сделано для этого.
Либерфорс

6
На самом деле from pprint import pprint; pprint(vars(object))дал мне действительно хороший вид на содержание моего объекта. Спасибо @liberforce
Н. Макс

лучший способ увидеть объект и его содержимое в строке
Питер Краусс

Это отличный способ увидеть объекты, которые реализуют любые методы представления, или такие объекты, как googleapiclient.errors.HttpError, которые, когда вы их печатаете, наверняка выводят недостаточную информацию, спасибо @ mtasic85
Фелипе Вальдес

65

Сначала прочитайте источник.

Во-вторых, используйте dir()функцию.


92
Я бы изменил этот порядок.
Байер

5
Источник более информативен, чем dir (), и лучше развивает привычку.
С.Лотт

14
Позволю себе не согласиться. Функция dir () работает намного быстрее, и в 99% случаев вы найдете то, что вам нужно, в сочетании с помощью help ().
Байер

7
Я согласен с обычно бесполезным. В большинстве случаев достаточно простого вызова dir (), что избавит вас от необходимости просматривать исходный код.
Саша Чедыгов

3
Иногда полезно проверять объекты во время выполнения, а читать источники - нет. Например, классы httplib.py и их методы :).
Денис Барменков

61

Я удивлен, что никто не упомянул помощь еще!

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

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

foo()
    foo!

С помощью справки вы можете прочитать строку документации и получить представление о том, какие атрибуты может иметь класс, что очень полезно.


Затем вы используете другие методы, упомянутые здесь. Но если есть документация, считайте ее каноном.
Эдвард Фальк

Я не уверен, что Python обновил эту функцию за последние несколько лет, но «help (object_name)» предоставляет полный обзор в высоко структурированном формате. Это хранитель. Спасибо.
Брайан Кугельман

27

Если это для исследования, чтобы увидеть, что происходит, я бы порекомендовал посмотреть на IPython . Это добавляет различные ярлыки для получения объектов документации, свойств и даже исходного кода. Например, добавив "?" функция даст справку для объекта (по сути, ярлык для «help (obj)», когда используется два? 's ("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 также часто полезно, если вы имеете дело с обертыванием или манипулированием функциями, так как оно даст имена и значения по умолчанию параметров функции.


18

Если вы заинтересованы в GUI для этого, взгляните на objbrowser . Он использует модуль проверки из стандартной библиотеки Python для внутреннего анализа объекта.

objbrowserscreenshot


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, если вы просто добавляете скобки вокруг отпечатков.
КонстантинK

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, которые ищут альтернативу 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

Если вы хотите посмотреть на параметры и методы, как уже отмечали другие, вы можете использовать pprintилиdir()

Если вы хотите увидеть фактическое значение содержимого, вы можете сделать

object.__dict__


4

Два отличных инструмента для проверки кода:

  1. IPython . Терминал Python, который позволяет вам проверить с помощью вкладки завершения.

  2. Затмение с плагином PyDev . Он имеет отличный отладчик, который позволяет разбивать на заданном месте и проверять объекты, просматривая все переменные в виде дерева. Вы даже можете использовать встроенный терминал, чтобы попробовать код в этом месте или набрать объект и нажать «.» чтобы он дал подсказки кода для вас.

введите описание изображения здесь




3

Если вам интересно посмотреть исходный код функции, соответствующей объекту myobj, вы можете ввести iPythonили Jupyter Notebook:

myobj??


2
import pprint

pprint.pprint(obj.__dict__)

или

pprint.pprint(vars(obj))

Хотя этот код может ответить на вопрос, предоставление дополнительного контекста относительно того, как и / или почему он решает проблему, улучшит долгосрочную ценность ответа.
Александр

1

Если вы хотите заглянуть внутрь живого объекта, то inspectмодуль python - хороший ответ. В общем, это работает для получения исходного кода функций, которые определены в исходном файле где-то на диске. Если вы хотите получить источник живых функций и лямбда-выражений, которые были определены в интерпретаторе, вы можете использовать dill.source.getsourceиз 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. Не уверен, работает ли он в более ранних версиях

ОБНОВЛЕНИЕ: Это не работает на всех типах объектов. Если вы встретите один из этих типов (например, объект запроса), используйте вместо этого один из следующих:

  • dir(object())

или

import pprint затем: pprint.pprint(object.__dict__)


1
Не работает с объектом «Запрос» «Объект« Запрос »не имеет атрибута« stringify »»
AlxVallejo
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.