Я ищу здесь что-то вроде функции PHP print_r.
Это сделано для того, чтобы я мог отлаживать свои сценарии, наблюдая за состоянием рассматриваемого объекта.
Вы просите атрибуты, не так ли? Вопрос вводит в заблуждение, потому что имущество имеет особое значение в Python, которое отличается от значения атрибут. Если я прав, может быть, вы захотите перефразировать свой вопрос?






Для этого вы можете использовать функцию "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
def dump(obj):
for attr in dir(obj):
print("obj.%s = %r" % (attr, getattr(obj, attr)))
Существует множество сторонних функций, которые добавляют такие вещи, как обработка исключений, печать национальных / специальных символов, рекурсивный переход во вложенные объекты и т. д. В соответствии с предпочтениями их авторов. Но все они в основном сводятся к этому.
unpythonic, потому что следует не изобретено здесь
Чего-чего? Конечно, вы можете использовать функцию getmembers() в стандартном модуле inspect, но я подумал, что это будет более полезно, поскольку оно показывает, как проводить самоанализ в целом.
даже тогда это подает плохой пример, потому что вы по существу переопределили obj .__ dict__.
НИСКОЛЬКО. dir (obj) показывает свойства, которых нет в __dict__ (например, __doc__ и __module__). Более того, __dict__ вообще не работает для объектов, объявленных с помощью __slots__. В общем, __dict__ показывает свойства уровня пользователя, которые фактически хранятся в словаре внутри. dir () показывает больше.
О чем ты говоришь? как __module__, так и __doc__ находятся в __dict__!
Некоторые классы / объекты не содержат атрибутов / членов __dict__. Я знаю, что это безумие, но это правда. Встроенные модули, такие как int и str или re.MatchObject, являются типичными примерами. Попробуйте 'hello'.__dict__, затем попробуйте dir('hello')
Что ж, этот ответ, по крайней мере, печатает имена атрибутов и то и другое, значения и, в случае, если объект не имеет dict (например, возврат от, скажем, QtGui.QMdiSubWindow.sizePolicy()), что мне нравится в нем.
Мне нравится вариант vars / pprint, указанный выше, но это хорошо, поскольку не требует включения библиотек.
LOL Tenable использует это в своей библиотеке Python Nessus (см. Функцию objdump) github.com/tenable/nessrest/blob/…
Действительно… дословно! Вау :-D github.com/tenable/nessrest/blob/…
Меня не волнует, «непифоническое» это или еще много чего. Он выполняет свою работу, и это единственное, что имеет значение при отладке.
Лучший ответ на данный момент. К черту "непифонические" подходы :)))
реж был упомянут, но это даст вам только имена атрибутов. Если вам нужны их значения, попробуйте __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(), 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__'}
Удивительно, но кажется, что не все объекты имеют член __dict__ (например, re.MatchObject), но встроенный dir() работает для всех объектов.
print re.compile(r'slots').search('No slots here either.').__slots__
@hobs: вы знаете, что "совещайся!" означает «смотри также», «сравнивай»? Я знаю, что у спичечных объектов нет слотов. Я не об этом пытался сказать.
Новый для меня. Спасибо. Точка запустила синтаксический анализатор пути модуля в моем мозгу. Никогда даже не рассматривал латинский «модуль».
почему бы вам не рассказать больше о модуле inspect в своем ответе? Думаю, это ближе всего к print_r или var_dump.
Вопрос не в том, чтобы смешивать две разные вещи. Функция var работает так, как требуется: stackoverflow.com/posts/193539/revisions
Как же тогда получить доступ к значениям атрибутов, перечисленных dir()? dir() возвращает только список имен, и не все из них существуют в vars() или в атрибуте __dict__.
что вы имеете в виду "вы действительно смешиваете две разные вещи."?
Относительно модуля inspect: метод - inspect.getmembers, см. Также этот ответ.
Вы хотите, чтобы vars() был смешан с pprint():
from pprint import pprint
pprint(vars(your_object))
vars() просто возвращает __dict__ своего аргумента, и это также является резервным вариантом dir() в случае отсутствия метода __dir__. так что используйте в первую очередь dir(), как я уже сказал.
@hop: dir() дает вам все встроенные вещи, которые вам, вероятно, не нужны, например, __str__ и __new__. var() - нет.
Это не работает на наборах и других объектах, у которых нет атрибута __dict__.
это абсолютно хорошие ответы, добавив еще: from inspect import getmembers
@hop, vars() дает значения полей, а dir() оставляет их загадкой.
Чтобы распечатать текущее состояние объекта, вы можете:
>>> obj # in an interpreter
или же
print repr(obj) # in a script
или же
print obj
Для ваших классов определите методы __str__ или __repr__. Из Документация Python:
__repr__(self)Called by therepr()built-in function and by string conversions (reverse quotes) to compute the "official" string representation of an object. If at all possible, this should look like a valid Python expression that could be used to recreate an object with the same value (given an appropriate environment). If this is not possible, a string of the form "<...some useful description...>" should be returned. The return value must be a string object. If a class defines repr() but not__str__(), then__repr__()is also used when an "informal" string representation of instances of that class is required. This is typically used for debugging, so it is important that the representation is information-rich and unambiguous.
__str__(self)Called by thestr()built-in function and by the print statement to compute the "informal" string representation of an object. This differs from__repr__()in that it does not have to be a valid Python expression: a more convenient or concise representation may be used instead. The return value must be a string object.
Эта опция полезна для печати строк, объединенных с содержимым объекта: print "DEBUG: object value: " + repr(obj)
Пример метапрограммирования Сбросить объект с помощью магии:
$ 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>
Он немного устарел, но все еще работает.
В большинстве случаев использование __dict__ или dir() предоставит вам нужную информацию. Если вам понадобится больше деталей, стандартная библиотека включает модуль осмотреть, который позволяет получить впечатляющее количество деталей. Некоторые из настоящих кусочков информации включают в себя:
Если вы просто ищете «какие значения атрибутов есть у моего объекта?», То dir() и __dict__, вероятно, подойдут. Если вы действительно хотите вникнуть в текущее состояние произвольных объектов (имея в виду, что в python почти все является объектом), то inspect заслуживает внимания.
Использовал ваше объяснение при проверке, чтобы улучшить наиболее полный ответ. Надеюсь, с тобой все в порядке.
pprint содержит «красивый принтер» для создания эстетически приятных представлений ваших структур данных. Средство форматирования создает представления структур данных, которые могут быть правильно проанализированы интерпретатором, а также легко читаются человеком. Вывод хранится в одной строке, если это возможно, и с отступом при разделении на несколько строк.
Возможно, стоит проверить -
Есть ли Python-эквивалент Perl Data :: Dumper?
Моя рекомендация такая -
https://gist.github.com/1071857
Обратите внимание, что в perl есть модуль под названием Data :: Dumper, который переводит данные объекта обратно в исходный код perl (NB: он НЕ переводит код обратно в исходный код, и почти всегда вы не хотите, чтобы функции метода объекта на выходе). Это можно использовать для сохранения, но обычно это делается для отладки.
Есть ряд вещей, которые стандартный python pprint не может достичь, в частности, он просто перестает спускаться, когда видит экземпляр объекта и дает вам внутренний шестнадцатеричный указатель объекта (эээ, этот указатель не очень часто используется путь). Итак, вкратце, python - это великолепная объектно-ориентированная парадигма, но инструменты, которые вы получаете из коробки, предназначены для работы с чем-то другим, кроме объектов.
Perl Data :: Dumper позволяет вам контролировать, насколько глубоко вы хотите зайти, а также обнаруживает циклические связанные структуры (что действительно важно). В Perl этого процесса принципиально легче достичь, потому что у объектов нет особой магии, кроме их благословения (универсально четко определенный процесс).
Это должен быть пип, а дебют - не только суть!
> Итак, вкратце, python - это все об этой замечательной объектно-ориентированной парадигме, но инструменты, которые вы получаете из коробки, предназначены для работы с чем-то другим, кроме объектов ... Довольно претензия, когда единственным примером, который вы предоставляете, является модуль второстепенной важности.
@memeplex где написано, что python - это все о OOP?
Хорошо, он просто говорит, что это все об этом великом ООП, мое плохое.
это только для 2.7
Почему не что-нибудь простое:
for key,value in obj.__dict__.iteritems():
print key,value
Разве это не должно быть for key,value in obj.__dict__.iteritems(): print key,value?
Мне нужно было распечатать информацию DEBUG в некоторых журналах, и я не смог использовать 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 not JSON serializable" в Python?
Хорошо, да, пришлось установить pymongo, чтобы использовать его.
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))
Если вы используете это для отладки и вам просто нужен рекурсивный дамп всего, принятый ответ неудовлетворителен, потому что он требует, чтобы ваши классы уже имели хорошие реализации __str__. Если это не так, это работает намного лучше:
import json
print(json.dumps(YOUR_OBJECT,
default=lambda obj: vars(obj),
indent=1))
это не сработало на python 3. Пришлось установить pymongo и сделать это в соответствии с ответом @Clark
как и многие другие ответы здесь TypeError: vars() argument must have __dict__ attribute
Это распечатает все содержимое объекта рекурсивно в формате 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)
Вы можете попробовать Flask Debug Toolbar.
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)
Попробуйте Симпатичная
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)
именно то, что я искал для быстрой отладки :), отличная находка!
маленькая подсказка: добавьте depth = 6 (или сколько вам нужно) в качестве одного из параметров для него, и детали рекурсии могут пойти дальше :). Одна из вещей, которые мне нравятся в том, как он печатает списки, - это то, что он показывает первые 2 записи и последние 2 записи, чтобы вы знали, что это работает.
Просто попробуйте пчелиный отпечаток.
Это поможет вам не только с печатью переменных объекта, но и с красивым выводом, например:
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))
не получить ошибок, но не рекурсивно, поэтому просто получите много шестнадцатеричных адресов
Я поддержал ответ, в котором упоминается только pprint. Чтобы было ясно, если вы хотите увидеть все значения в сложной структуре данных, сделайте что-нибудь вроде:
from pprint import pprint
pprint(my_var)
Где my_var - интересующая вас переменная. Когда я использовал pprint(vars(my_var)), я ничего не получил, и другие ответы здесь не помогли, или метод выглядел излишне длинным. Кстати, в моем конкретном случае проверяемый мной код содержал словарь словарей.
Стоит отметить, что с некоторыми настраиваемыми классами вы можете получить бесполезный вывод <someobject.ExampleClass object at 0x7f739267f400>. В этом случае вам, возможно, придется реализовать метод __str__ или попробовать другие решения. Я все еще хотел бы найти что-то простое, что работало бы во всех сценариях, без сторонних библиотек.
> с некоторыми кастомными классами ... Вот почему я не фанат питона. Что "иногда" работает, а "иногда" нет
Рекомендую использовать 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__.
Is there a built-in function to print all the current properties and values of an object?
Нет. Ответ, получивший наибольшее количество голосов, исключает некоторые виды атрибутов, а принятый ответ показывает, как получить атрибуты все, включая методы и части непубличного 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': ''}
Но, возможно, мы знаем, что наша недвижимость не дорогая. Мы можем захотеть изменить логику, чтобы включить их тоже. И, возможно, мы хотим вместо этого исключить дескрипторы данных Другиеобычай.
Затем нам нужно дополнительно настроить эту функцию. И поэтому логично, что у нас не может быть встроенной функции, которая волшебным образом точно знает, что мы хотим, и предоставляла бы это. Это функциональность, которую мы должны создать сами.
Встроенной функции для этого нет, и вы должны делать то, что наиболее семантически подходит для вашей ситуации.
Это работает независимо от того, как ваши переменные определены внутри класса, внутри __init__ или снаружи.
your_obj = YourObj()
attrs_with_value = {attr: getattr(your_obj, attr) for attr in dir(your_obj)}
См. Обзор того, как различные подходы, описанные здесь, могут применяться к ваша ситуация, в ответе @Aaron_Hall.