Существует ли встроенная функция для печати всех текущих свойств и значений объекта?
-
08-07-2019 - |
Вопрос
Итак, то, что я ищу здесь, это что-то вроде PHP print_r функция.Это делается для того, чтобы я мог отлаживать свои скрипты, видя, в каком состоянии находится рассматриваемый объект.
Решение
Вы действительно смешиваете воедино две разные вещи.
Использование dir()
, vars()
или тот inspect
модуль для получения того, что вас интересует (я использую __builtins__
в качестве примера;вместо этого вы можете использовать любой объект).
>>> l = dir(__builtins__)
>>> d = __builtins__.__dict__
Распечатайте этот словарь так, как вам заблагорассудится:
>>> print l
['ArithmeticError', 'AssertionError', 'AttributeError',...
или
>>> from pprint import pprint
>>> pprint(l)
['ArithmeticError',
'AssertionError',
'AttributeError',
'BaseException',
'DeprecationWarning',
...
>>> pprint(d, indent=2)
{ 'ArithmeticError': <type 'exceptions.ArithmeticError'>,
'AssertionError': <type 'exceptions.AssertionError'>,
'AttributeError': <type 'exceptions.AttributeError'>,
...
'_': [ 'ArithmeticError',
'AssertionError',
'AttributeError',
'BaseException',
'DeprecationWarning',
...
Красивая печать также доступна в интерактивном отладчике в виде команды:
(Pdb) pp vars()
{'__builtins__': {'ArithmeticError': <type 'exceptions.ArithmeticError'>,
'AssertionError': <type 'exceptions.AssertionError'>,
'AttributeError': <type 'exceptions.AttributeError'>,
'BaseException': <type 'exceptions.BaseException'>,
'BufferError': <type 'exceptions.BufferError'>,
...
'zip': <built-in function zip>},
'__file__': 'pass.py',
'__name__': '__main__'}
Другие советы
Вы хотите vars()
смешать с pprint()
:
from pprint import pprint
pprint(vars(your_object))
def dump(obj):
for attr in dir(obj):
print("obj.%s = %r" % (attr, getattr(obj, attr)))
Существует множество сторонних функций, которые добавляют такие вещи, как обработка исключений, печать национальных / специальных символов, повторное использование вложенных объектов и т. д. в соответствии с предпочтениями их авторов. Но все они в основном сводятся к этому.
dir уже упоминалось, но это даст вам только имена атрибутов. Если вы также хотите их значения, попробуйте __dict __.
class O:
def __init__ (self):
self.value = 3
o = O()
Вот вывод:
>>> o.__dict__
{'value': 3}
Чтобы распечатать текущее состояние объекта, вы можете:
>>> obj # in an interpreter
или
print repr(obj) # in a script
или
print obj
Для ваших классов определите __str__
или __repr__
методы.Из самого Документация на Python:
__repr__(self)
Вызванныйrepr()
встроенная функция и по строке преобразования (обратные кавычки) для вычисления "официальной" строки представления объекта.Если это вообще возможно , это должно выглядеть как допустимое выражение Python, которое можно использовать для воссоздания объекта с тем же значением (при условии соответствующей среды).Если это невозможно, строка вида "<...некоторое полезное описание ...>" должно быть возвращено.Возвращаемое значение должно быть строковым объектом.Если класс определяет репр() но не__str__()
, тогда__repr__()
является также используется, когда требуется "неформальная" строка представление экземпляров этого класса.Обычно это используется для отладки, поэтому важно чтобы представление было информационно насыщенным и однозначным.
__str__(self)
Вызванныйstr()
встроенная функция и оператор print для вычисления "неформального" строкового представления объекта.Это отличается от__repr__()
в этом это не обязательно должен быть действительным на Python выражение:вместо этого можно использовать более удобное или краткое представление .Возвращаемое значение должно быть объектом string.
Вы можете использовать " dir () " Функция для этого.
>>> import sys
>>> dir(sys)
['__displayhook__', '__doc__', '__excepthook__', '__name__', '__stderr__', '__stdin__', '__stdo
t__', '_current_frames', '_getframe', 'api_version', 'argv', 'builtin_module_names', 'byteorder
, 'call_tracing', 'callstats', 'copyright', 'displayhook', 'dllhandle', 'exc_clear', 'exc_info'
'exc_type', 'excepthook', 'exec_prefix', 'executable', 'exit', 'getcheckinterval', 'getdefault
ncoding', 'getfilesystemencoding', 'getrecursionlimit', 'getrefcount', 'getwindowsversion', 'he
version', 'maxint', 'maxunicode', 'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_
ache', 'platform', 'prefix', 'ps1', 'ps2', 'setcheckinterval', 'setprofile', 'setrecursionlimit
, 'settrace', 'stderr', 'stdin', 'stdout', 'subversion', 'version', 'version_info', 'warnoption
', 'winver']
>>>
Еще одна полезная функция - помощь.
>>> help(sys)
Help on built-in module sys:
NAME
sys
FILE
(built-in)
MODULE DOCS
http://www.python.org/doc/current/lib/module-sys.html
DESCRIPTION
This module provides access to some objects used or maintained by the
interpreter and to functions that interact strongly with the interpreter.
Dynamic objects:
argv -- command line arguments; argv[0] is the script pathname if known
Может быть стоит проверить -
Есть ли Python, эквивалентный Perl's Data :: Dumper? а> р>
Моя рекомендация такая - https://gist.github.com/1071857 Обратите внимание, что в perl есть модуль Data :: Dumper, который переводит данные объекта обратно в исходный код perl (примечание: он НЕ переводит код обратно в источник, и почти всегда вам не нужны функции метода объекта в выход). Это можно использовать для сохранения, но общая цель - отладка. Есть ряд вещей, которых не удается достичь стандартному python pprint, в частности, он просто останавливается, когда видит экземпляр объекта, и выдает внутренний шестнадцатеричный указатель объекта (ошибочно, этот указатель не очень использования кстати). Итак, в двух словах, Python - это все об этой великолепной объектно-ориентированной парадигме, но инструменты, которые вы получаете из коробки, предназначены для работы с чем-то, кроме объектов. Perl Data :: Dumper позволяет вам контролировать, насколько глубоко вы хотите зайти, а также обнаруживает циклически связанные структуры (это действительно важно). Этот процесс принципиально проще реализовать в Perl, потому что у объектов нет особой магии, кроме их благословения (универсально четко определенного процесса).
В большинстве случаев, используя __dict__
или dir()
это даст вам нужную информацию.Если вам понадобится более подробная информация, стандартная библиотека включает в себя Осмотр модуль, который позволяет получить впечатляющее количество деталей.Некоторые из реальных источников информации включают в себя:
- имена параметров функции и метода
- иерархии классов
- исходный код реализации функций/объектов класса
- локальные переменные вне объекта frame
Если вы просто ищете "какие значения атрибутов есть у моего объекта?", то dir()
и __dict__
вероятно, этого достаточно.Если вы действительно хотите разобраться в текущем состоянии произвольных объектов (имея в виду, что в python почти все является объектом), то inspect
заслуживает рассмотрения.
Пример метапрограммирования Сбросить объект с помощью магии . р>
$ cat dump.py
#!/usr/bin/python
import sys
if len(sys.argv) > 2:
module, metaklass = sys.argv[1:3]
m = __import__(module, globals(), locals(), [metaklass])
__metaclass__ = getattr(m, metaklass)
class Data:
def __init__(self):
self.num = 38
self.lst = ['a','b','c']
self.str = 'spam'
dumps = lambda self: repr(self)
__str__ = lambda self: self.dumps()
data = Data()
print data
Без аргументов.
$ python dump.py
<__main__.Data instance at 0x00A052D8>
С помощью утилит Gnosis :
$ python dump.py gnosis.magic MetaXMLPickler
<?xml version="1.0"?>
<!DOCTYPE PyObject SYSTEM "PyObjects.dtd">
<PyObject module="__main__" class="Data" id="11038416">
<attr name="lst" type="list" id="11196136" >
<item type="string" value="a" />
<item type="string" value="b" />
<item type="string" value="c" />
</attr>
<attr name="num" type="numeric" value="38" />
<attr name="str" type="string" value="spam" />
</PyObject>
Это немного устарело, но все еще работает.
Если вы используете это для отладки и хотите просто рекурсивный дамп всего, принятый ответ неудовлетворителен, поскольку требует, чтобы у ваших классов уже были хорошие реализации __str__
. Если это не так, это работает намного лучше:
import json
print(json.dumps(YOUR_OBJECT,
default=lambda obj: vars(obj),
indent=1))
Это распечатывает все содержимое объекта рекурсивно в формате с отступом json или yaml:
import jsonpickle # pip install jsonpickle
import json
import yaml # pip install pyyaml
serialized = jsonpickle.encode(obj, max_depth=2) # max_depth is optional
print json.dumps(json.loads(serialized), indent=4)
print yaml.dump(yaml.load(serialized), indent=4)
Я рекомендую использовать help(your_object)
.
help(dir)
If called without an argument, return the names in the current scope. Else, return an alphabetized list of names comprising (some of) the attributes of the given object, and of attributes reachable from it. If the object supplies a method named __dir__, it will be used; otherwise the default dir() logic is used and returns: for a module object: the module's attributes. for a class object: its attributes, and recursively the attributes of its bases. for any other object: its attributes, its class's attributes, and recursively the attributes of its class's base classes.
help(vars)
Without arguments, equivalent to locals(). With an argument, equivalent to object.__dict__.
Мне нужно было распечатать информацию отладки в некоторых журналах, и я не смог использовать pprint, потому что это сломало бы ее. Вместо этого я сделал это и получил практически то же самое.
DO = DemoObject()
itemDir = DO.__dict__
for i in itemDir:
print '{0} : {1}'.format(i, itemDir[i])
Для выгрузки " myObject ":
from bson import json_util
import json
print(json.dumps(myObject, default=json_util.default, sort_keys=True, indent=4, separators=(',', ': ')))
Я пробовал vars () и dir (); оба потерпели неудачу из-за того, что я искал. vars () не работал, потому что у объекта не было __dict__ (exceptions.TypeError: аргумент vars () должен иметь атрибут __dict__). dir () не то, что я искал: это просто список имен полей, не дает значений или структуру объекта.
Я думаю, что json.dumps () будет работать для большинства объектов без default = json_util.default, но у меня было поле datetime в объекте, поэтому стандартный сериализатор json не сработал. См. Как преодолеть & Quot; datetime.datetime не JSON-сериализуемый " в питоне?
from pprint import pprint
def print_r(the_object):
print ("CLASS: ", the_object.__class__.__name__, " (BASE CLASS: ", the_object.__class__.__bases__,")")
pprint(vars(the_object))
Попробуй приятная
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(), show_protected=True, show_static=True, show_properties=True)
Выходной сигнал:
__main__.A(_p = 8, foo = [0, 1, ..., 8, 9], s = 5)
pprint содержит & # 8220; красивый принтер < !> # 8221; для создания эстетически приятных представлений ваших структур данных. Форматировщик создает представления структур данных, которые могут быть правильно проанализированы интерпретатором, и которые также легко читаются человеком. Выходные данные хранятся в одной строке, если это возможно, и имеют отступ при разбивке на несколько строк.
Почему бы не что-то простое:
for key,value in obj.__dict__.iteritems():
print key,value
Я проголосовал за ответ, в котором упоминается только pprint. Чтобы было понятно, если вы хотите увидеть все значения в сложной структуре данных, сделайте что-то вроде:
from pprint import pprint
pprint(my_var)
Где my_var - ваша интересующая переменная. Когда я использовал pprint (vars (my_var)), я ничего не получил, и другие ответы здесь не помогли, или метод выглядел излишне длинным. Кстати, в моем конкретном случае проверяемый код содержал словарь словарей.
Стоит отметить, что с некоторыми пользовательскими классами вы можете просто получить бесполезный <someobject.ExampleClass object at 0x7f739267f400>
вид вывода. В этом случае вам может понадобиться реализовать метод __str__
или попробовать другие решения. Я все еще хотел бы найти что-то простое, которое работает во всех сценариях, без сторонних библиотек.
Просто попробуйте beeprint .
Это поможет вам не только распечатать переменные объекта, но и получить красивый вывод, например:
class(NormalClassNewStyle):
dicts: {
},
lists: [],
static_props: 1,
tupl: (1, 2)
Для всех, кто борется с
vars()
не возвращает все атрибуты.dir()
не возвращает значения атрибутов.
Выводится следующий код ВСЕ атрибуты obj
со своими ценностями:
for attr in dir(obj):
try:
print("obj.{} = {}".format(attr, getattr(obj, attr)))
except AttributeError:
print("obj.{} = ?".format(attr))
Вы можете попробовать панель инструментов отладки Flask.
https://pypi.python.org/pypi/Flask-DebugToolbar
from flask import Flask
from flask_debugtoolbar import DebugToolbarExtension
app = Flask(__name__)
# the toolbar is only enabled in debug mode:
app.debug = True
# set a 'SECRET_KEY' to enable the Flask session cookies
app.config['SECRET_KEY'] = '<replace with a secret key>'
toolbar = DebugToolbarExtension(app)