Ответы:
Вы действительно смешиваете две разные вещи.
Используйте 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__'}
print re.compile(r'slots').search('No slots here either.').__slots__
inspect
модуле в своем ответе? Я думаю, что это самая близкая вещь к print_r или var_dump.
dir()
, тогда? dir()
возвращает только список имен, и не все из них существуют в vars()
или в __dict__
атрибуте.
Вы хотите vars()
смешать с pprint()
:
from pprint import pprint
pprint(vars(your_object))
vars()
просто возвращает __dict__
свой аргумент, и это также запасной вариант, dir()
если нет __dir__
метода. так что используйте dir()
в первую очередь, как я уже сказал.
dir()
дает вам все встроенные в вещи , которые вы , вероятно , не заботятся о том, как __str__
и __new__
. var()
не делает.
__dict__
атрибута.
def dump(obj):
for attr in dir(obj):
print("obj.%s = %r" % (attr, getattr(obj, attr)))
Существует множество сторонних функций, которые добавляют такие вещи, как обработка исключений, печать национальных / специальных символов, повторное использование вложенных объектов и т. Д. В соответствии с предпочтениями их авторов. Но все они в основном сводятся к этому.
getmembers()
функцию в стандартном inspect
модуле, но я подумал, что это было бы более полезно, поскольку оно иллюстрирует, как сделать самоанализ в целом.
__dict__
(такие как __doc__
и __module__
). Кроме того, __dict__
совсем не работает для объектов, объявленных с __slots__
. В общем, __dict__
показывает пользовательские свойства, которые на самом деле хранятся в словаре внутри. dir () показывает больше.
__dict__
атрибутов / членов. Я знаю, что это безумие, но это правда. Встроенные модули, такие как int
and str
или re.MatchObject
s, являются типичными примерами. Попробуй 'hello'.__dict__
, потом попробуйdir('hello')
dir был упомянут, но это даст вам только имена атрибутов. Если вы хотите их значения, попробуйте __dict__.
class O:
def __init__ (self):
self.value = 3
o = O()
Вот вывод:
>>> o.__dict__
{'value': 3}
set
не имеет __dict__
, поэтому для них это не удастсяAttributeError: 'set' object has no attribute '__dict__'
Вы можете использовать функцию "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
Чтобы напечатать текущее состояние объекта, вы можете:
>>> obj # in an interpreter
или
print repr(obj) # in a script
или
print obj
Для ваших занятий определите __str__
или __repr__
методы. Из документации Python :
__repr__(self)
Вызываетсяrepr()
встроенной функцией и преобразованиями строк (обратными кавычками) для вычисления «официального» строкового представления объекта. Если это вообще возможно, это должно выглядеть как допустимое выражение Python, которое можно использовать для воссоздания объекта с тем же значением (с учетом соответствующей среды). Если это невозможно, должна быть возвращена строка вида "<... некоторое полезное описание ...>". Возвращаемое значение должно быть строковым объектом. Если класс определяет repr (), но нет__str__()
, тогда__repr__()
он также используется, когда требуется «неформальное» строковое представление экземпляров этого класса. Обычно это используется для отладки, поэтому важно, чтобы представление было насыщенным информацией и однозначным.
__str__(self)
Вызываетсяstr()
встроенной функцией и оператором print для вычисления «неформального» строкового представления объекта. Это отличается от того,__repr__()
что оно не обязательно должно быть допустимым выражением Python: вместо него можно использовать более удобное или краткое представление. Возвращаемое значение должно быть строковым объектом.
print "DEBUG: object value: " + repr(obj)
Может стоит проверить -
Есть ли Python эквивалентный Perl Data :: Dumper?
Моя рекомендация такая -
https://gist.github.com/1071857
Обратите внимание, что в perl есть модуль Data :: Dumper, который переводит данные объекта обратно в исходный код perl (примечание: он НЕ переводит код обратно в исходный код, и почти всегда вам не нужны функции метода объекта в выходных данных). Это может использоваться для постоянства, но общая цель для отладки.
Есть ряд вещей, которые не удается выполнить стандартному python pprint, в частности он просто останавливается, когда видит экземпляр объекта, и выдает внутренний шестнадцатеричный указатель объекта (ошибочно, этот указатель не очень полезен путь). Итак, в двух словах, Python - это все об этой великолепной объектно-ориентированной парадигме, но инструменты, которые вы получаете из коробки, предназначены для работы с чем-то, кроме объектов.
Perl Data :: Dumper позволяет вам контролировать, насколько глубоко вы хотите зайти, а также обнаруживает циклически связанные структуры (это действительно важно). Этот процесс принципиально проще осуществить в Perl, потому что у объектов нет особой магии, кроме их благословения (универсально четко определенный процесс).
Я рекомендую использовать 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__.
В большинстве случаев, используя __dict__
или dir()
вы получите необходимую информацию. Если вам нужно больше подробностей, стандартная библиотека включает в себя модуль проверки , который позволяет получить впечатляющее количество деталей. Некоторые из реальных кусочков информации включают в себя:
Если вы просто ищете «какие значения атрибутов имеет мой объект?», То dir()
и __dict__
, вероятно, достаточно. Если вы действительно хотите заглянуть в текущее состояние произвольных объектов (имея в виду, что в python почти все является объектом), то inspect
стоит рассмотреть.
Есть ли встроенная функция для печати всех текущих свойств и значений объекта?
Нет. Ответ с наибольшим количеством голосов исключает некоторые виды атрибутов, и принятый ответ показывает, как получить все атрибуты, включая методы и части закрытого API. Но нет хорошего полного встроенного функции.
Таким образом, короткое следствие заключается в том, что вы можете написать свой собственный, но он будет вычислять свойства и другие вычисляемые дескрипторы данных, которые являются частью общедоступного API, и вы можете этого не захотеть:
from pprint import pprint
from inspect import getmembers
from types import FunctionType
def attributes(obj):
disallowed_names = {
name for name, value in getmembers(type(obj))
if isinstance(value, FunctionType)}
return {
name: getattr(obj, name) for name in dir(obj)
if name[0] != '_' and name not in disallowed_names and hasattr(obj, name)}
def print_attributes(obj):
pprint(attributes(obj))
Обратите внимание на применение ответа, получившего наибольшее количество голосов в классе с множеством различных типов данных:
from pprint import pprint
class Obj:
__slots__ = 'foo', 'bar', '__dict__'
def __init__(self, baz):
self.foo = ''
self.bar = 0
self.baz = baz
@property
def quux(self):
return self.foo * self.bar
obj = Obj('baz')
pprint(vars(obj))
только отпечатки:
{'baz': 'baz'}
Потому что возвращает vars
только__dict__
объект, и это не копия, поэтому, если вы изменяете dict, возвращаемый vars, вы также изменяете __dict__
сам объект.
vars(obj)['quux'] = 'WHAT?!'
vars(obj)
возвращает:
{'baz': 'baz', 'quux': 'WHAT?!'}
- что плохо, потому что quux - это свойство, которое мы не должны устанавливать и не должны находиться в пространстве имен ...
Применение совета в принятом в настоящее время ответе (и других) не намного лучше:
>>> dir(obj)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', 'bar', 'baz', 'foo', 'quux']
Как мы видим, dir
возвращает только все (на самом деле только большинство) из имен, связанных с объектом.
inspect.getmembers
Упоминается в комментариях, также имеет недостатки - возвращает все имена и значения.
При обучении мои ученики создают функцию, которая предоставляет семантически открытый API объекта:
def api(obj):
return [name for name in dir(obj) if name[0] != '_']
Мы можем расширить это, чтобы предоставить копию семантического пространства имен объекта, но нам нужно исключить __slots__
те, которые не назначены, и, если мы серьезно относимся к запросу «текущих свойств», нам нужно исключить вычисляемые свойства (так как они могут стать дорогими и могут быть истолкованы как не «текущие»):
from types import FunctionType
from inspect import getmembers
def attrs(obj):
disallowed_properties = {
name for name, value in getmembers(type(obj))
if isinstance(value, (property, FunctionType))}
return {
name: getattr(obj, name) for name in api(obj)
if name not in disallowed_properties and hasattr(obj, name)}
И теперь мы не рассчитываем и не показываем свойство quux:
>>> attrs(obj)
{'bar': 0, 'baz': 'baz', 'foo': ''}
Но, возможно, мы знаем, что наша недвижимость не дорогая. Мы можем захотеть изменить логику, чтобы включить их. И, возможно, мы хотим исключить другие пользовательские дескрипторы данных.
Затем нам нужно дополнительно настроить эту функцию. И поэтому имеет смысл, что у нас не может быть встроенной функции, которая волшебным образом точно знает, чего мы хотим, и обеспечивает ее. Это функциональность, которую мы должны создать сами.
Нет встроенной функции, которая делает это, и вы должны делать то, что наиболее семантически подходит для вашей ситуации.
FunctionType
. Но очень полезно - спасибо!
Пример метапрограммирования Dump объект с магией :
$ 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 Utils :
$ 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))
TypeError: vars() argument must have __dict__ attribute
Попробуйте 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(), show_protected=True, show_static=True, show_properties=True)
Вывод:
__main__.A(_p = 8, foo = [0, 1, ..., 8, 9], s = 5)
Это распечатывает все содержимое объекта рекурсивно в формате с отступом 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)
Я проголосовал за ответ, который упоминает только pprint. Для ясности, если вы хотите увидеть все значения в сложной структуре данных, сделайте что-то вроде:
from pprint import pprint
pprint(my_var)
Где my_var - ваша переменная интереса. Когда я использовал, pprint(vars(my_var))
я ничего не получил, и другие ответы здесь не помогли, или метод выглядел излишне длинным. Кстати, в моем конкретном случае проверяемый код содержал словарь словарей.
Стоит отметить, что с некоторыми пользовательскими классами вы можете просто получить бесполезный <someobject.ExampleClass object at 0x7f739267f400>
вид вывода. В этом случае вам может понадобиться реализовать __str__
метод или попробовать другие решения. Я все еще хотел бы найти что-то простое, которое работает во всех сценариях, без сторонних библиотек.
Мне нужно было распечатать информацию отладки в некоторых журналах и не смог использовать 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 не сработал. Смотрите Как преодолеть «datetime.datetime, не JSON serializable» в python?
Почему не что-то простое:
for key,value in obj.__dict__.iteritems():
print key,value
for key,value in obj.__dict__.iteritems(): print key,value
?
pprint содержит «симпатичный принтер» для создания эстетически приятных представлений о ваших структурах данных. Форматировщик создает представления структур данных, которые могут быть правильно проанализированы интерпретатором, и которые также легко читаются человеком. Выходные данные хранятся в одной строке, если это возможно, и имеют отступ, если разделены на несколько строк.
Просто попробуйте 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)
Мне нравится работать с ключами или значениями встроенных типов объектов Python .
Для атрибутов независимо от того, являются ли они методами или переменными:
o.keys()
Для значений этих атрибутов:
o.values()
__dict__
члена (re.MatchObject
например), но встроенные функцииdir()
работают для всех объектов.