|
|||||||
Is there a built-in function to print all the current properties and values of an object?
Время создания: 16.07.2018 11:28
Текстовые метки: python pretty print object vars
Раздел: Python
Запись: Velonski/mytetra-database/master/base/1531721732ctj8w4p3ol/text.html на raw.githubusercontent.com
|
|||||||
|
|||||||
So what I'm looking for here is something like PHP's print_r function. This is so I can debug my scripts by seeing what's the state of the object in question. python debugging introspection pretty-print python-datamodel shareimprove this question edited Jun 19 '17 at 13:00 martineau 60.6k785158 asked Oct 10 '08 at 16:19 fuentesjr 19.7k256475 add a comment 22 Answers active oldest votes up vote 413 down vote accepted You are really mixing together two different things. Use dir(), vars() or the inspect module to get what you are interested in (I use __builtins__ as an example; you can use any object instead). >>> l = dir(__builtins__) >>> d = __builtins__.__dict__ Print that dictionary however fancy you like: >>> print l ['ArithmeticError', 'AssertionError', 'AttributeError',... or >>> 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', ... Pretty printing is also available in the interactive debugger as a command: (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__'} shareimprove this answer edited May 4 '17 at 14:04 answered Oct 10 '08 at 17:27 hop 27.2k84960 13 Surprisingly, it seems not all objects have a __dict__ member (an re.MatchObject for instance), but builtin dir() works for all objects. – hobs Mar 18 '12 at 3:47 3 @hobs: cf. __slots__! – hop Mar 18 '12 at 18:46 print re.compile(r'slots').search('No slots here either.').__slots__ – hobs Mar 19 '12 at 1:40 2 New one to me. Thx. The dot triggered my brain's module path parser. Never even considered the Latin "module". – hobs Mar 20 '12 at 6:52 3 why don't you talk more about inspect module in your answer? I think it is the closest thing to print_r or var_dump. – Hai Phaikawl May 22 '12 at 10:56 show 1 more comment up vote 722 down vote You want vars() mixed with pprint(): from pprint import pprint pprint(vars(your_object)) shareimprove this answer edited Jun 9 '17 at 21:29 lmiguelvargasf 8,03796885 answered Oct 11 '08 at 1:16 Jeremy Cantrell 15.9k84574 41 most useful answer by far, and closest to PHP's print_r() as asked in the question – Noah Yetter Jun 27 '11 at 4:17 14 vars() simply returns the __dict__ of its argument and that is also the fallback of dir() in case there is no __dir__ method. so use dir() in the first place, as i said. – hop Dec 18 '11 at 20:16 21 @hop: dir() gives you all the built in things you probably don't care about like __str__ and __new__. var() doesn't. – Timmmm Jul 31 '12 at 17:23 14 If you're doing this in pdb, you don't need the import, just do pp vars(your_object) – wisbucky Jun 12 '14 at 18:35 7 This fails on sets and other objects that doesn't have __dict__ attribute. – anatoly techtonik Aug 24 '15 at 8:24 show 2 more comments up vote 137 down vote def dump(obj): for attr in dir(obj): print("obj.%s = %r" % (attr, getattr(obj, attr))) There are many 3rd-party functions out there that add things like exception handling, national/special character printing, recursing into nested objects etc. according to their authors' preferences. But they all basically boil down to this. shareimprove this answer edited Jan 15 at 17:09 answered Oct 10 '08 at 16:36 Dan Lenski 44.9k95492 4 unpythonic, because follows not-invented-here – hop Oct 10 '08 at 17:31 13 Say what? Sure, you can use the getmembers() function in the standard inspect module, but I thought this would be more useful in that it illustrates how to do introspection in general. – Dan Lenski Oct 10 '08 at 17:44 18 NOT AT ALL. dir(obj) shows properties that aren't found in __dict__ (such as __doc__ and __module__). Furthermore, __dict__ doesn't work at all for objects declared with __slots__. In general, __dict__ shows user-level properties that are actually stored in a dictionary internally. dir() shows more. – Dan Lenski Oct 10 '08 at 19:08 8 Some classes/objects don't contain any __dict__ attribute/member. I know it's crazy, but true. Built-ins like int and str or re.MatchObjects are common examples. Try 'hello'.__dict__, then try dir('hello') – hobs Mar 18 '12 at 4:50 2 Well, this answer at least prints both attributes' names and values, in case an object doesn't have a dict (like the return from, say, QtGui.QMdiSubWindow.sizePolicy()), which is what I like about it. – sdaau Nov 11 '13 at 0:27 show 6 more comments up vote 35 down vote dir has been mentioned, but that'll only give you the attributes' names. If you want their values as well try __dict__. class O: def __init__ (self): self.value = 3 o = O() Here is the output: >>> o.__dict__ {'value': 3} shareimprove this answer edited Jul 28 '17 at 15:29 Vadim Kotov 3,95852947 answered Oct 10 '08 at 16:44 eduffy 28.5k87785 4 Objects like set doesn't have __dict__, so for them it will fail with AttributeError: 'set' object has no attribute '__dict__' – anatoly techtonik Aug 24 '15 at 8:27 add a comment up vote 19 down vote To print the current state of the object you might: >>> obj # in an interpreter or print repr(obj) # in a script or print obj For your classes define __str__ or __repr__ methods. From the Python documentation: __repr__(self) Called by the repr() 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 the str() 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. shareimprove this answer answered Oct 11 '08 at 7:29 jfs 245k66506994 This option is useful for printing strings concatenated with the content of the object: print "DEBUG: object value: " + repr(obj) – AlejandroVD Nov 10 '15 at 15:27 add a comment up vote 17 down vote You can use the "dir()" function to do this. >>> 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'] >>> Another useful feature is help. >>> 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 shareimprove this answer edited Oct 10 '08 at 20:05 S.Lott 305k64426707 answered Oct 10 '08 at 16:20 Joe Skora 10.9k42935 add a comment up vote 12 down vote Might be worth checking out -- Is there a Python equivalent to Perl's Data::Dumper? My recommendation is this -- https://gist.github.com/1071857 Note that perl has a module called Data::Dumper which translates object data back to perl source code (NB: it does NOT translate code back to source, and almost always you don't want to the object method functions in the output). This can be used for persistence, but the common purpose is for debugging. There are a number of things standard python pprint fails to achieve, in particular it just stops descending when it sees an instance of an object and gives you the internal hex pointer of the object (errr, that pointer is not a whole lot of use by the way). So in a nutshell, python is all about this great object oriented paradigm, but the tools you get out of the box are designed for working with something other than objects. The perl Data::Dumper allows you to control how deep you want to go, and also detects circular linked structures (that's really important). This process is fundamentally easier to achieve in perl because objects have no particular magic beyond their blessing (a universally well defined process). shareimprove this answer edited May 23 '17 at 10:31 Community♦ 11 answered Nov 15 '12 at 4:11 Tel 12112 This should be a pip and a deb not only a gist! – phobie Aug 4 '15 at 18:27 2 > So in a nutshell, python is all about this great object oriented paradigm, but the tools you get out of the box are designed for working with something other than objects... Quite a claim when the only example you're providing is a module of secondary importance. – memeplex May 31 '16 at 0:21 add a comment up vote 9 down vote In most cases, using __dict__ or dir() will get you the info you're wanting. If you should happen to need more details, the standard library includes the inspect module, which allows you to get some impressive amount of detail. Some of the real nuggests of info include: names of function and method parameters class hierarchies source code of the implementation of a functions/class objects local variables out of a frame object If you're just looking for "what attribute values does my object have?", then dir() and __dict__ are probably sufficient. If you're really looking to dig into the current state of arbitrary objects (keeping in mind that in python almost everything is an object), then inspect is worthy of consideration. shareimprove this answer edited Aug 24 '15 at 8:44 anatoly techtonik 11k58190 answered Oct 15 '08 at 14:53 William McVey 1282 Used your explanation on inspect to improve the most complete answer. Hope that's ok with you. – Fernando César Mar 11 at 19:34 add a comment up vote 7 down vote A metaprogramming example Dump object with magic: $ 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 Without arguments: $ python dump.py <__main__.Data instance at 0x00A052D8> With 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> It is a bit outdated but still working. shareimprove this answer edited Mar 28 '09 at 15:43 answered Oct 11 '08 at 7:53 jfs 245k66506994 add a comment up vote 4 down vote If you're using this for debugging, and you just want a recursive dump of everything, the accepted answer is unsatisfying because it requires that your classes have good __str__ implementations already. If that's not the case, this works much better: import json print(json.dumps(YOUR_OBJECT, default=lambda obj: vars(obj), indent=1)) shareimprove this answer answered Nov 23 '14 at 21:20 Adam Cath 9912 this didn't work on python 3. Had to install pymongo and do it as per @Clark 's answer – Tim Ogilvy Apr 16 '15 at 8:04 Gives a circular reference error – dario_ramos Jul 25 '17 at 19:31 add a comment up vote 3 down vote I was needing to print DEBUG info in some logs and was unable to use pprint because it would break it. Instead I did this and got virtually the same thing. DO = DemoObject() itemDir = DO.__dict__ for i in itemDir: print '{0} : {1}'.format(i, itemDir[i]) shareimprove this answer answered Jun 28 '13 at 19:36 DaOneTwo 336 add a comment up vote 3 down vote To dump "myObject": from bson import json_util import json print(json.dumps(myObject, default=json_util.default, sort_keys=True, indent=4, separators=(',', ': '))) I tried vars() and dir(); both failed for what I was looking for. vars() didn't work because the object didn't have __dict__ (exceptions.TypeError: vars() argument must have __dict__ attribute). dir() wasn't what I was looking for: it's just a listing of field names, doesn't give the values or the object structure. I think json.dumps() would work for most objects without the default=json_util.default, but I had a datetime field in the object so the standard json serializer failed. See How to overcome "datetime.datetime not JSON serializable" in python? shareimprove this answer edited May 23 '17 at 12:18 Community♦ 11 answered Jun 26 '14 at 16:12 Clark 16413 is bson correct? – Tim Ogilvy Apr 16 '15 at 7:55 Okay yep had to install pymongo tho to use it. – Tim Ogilvy Apr 16 '15 at 8:09 add a comment up vote 3 down vote 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)) shareimprove this answer answered Jul 14 '14 at 15:01 32ndghost 311 Finally, something that actually worked. vars() was the key here – frostymarvelous Jul 14 '15 at 12:37 add a comment up vote 3 down vote Just try beeprint it help you with not only printing object variables, but beautiful output, like this: class(NormalClassNewStyle): dicts: { }, lists: [], static_props: 1, tupl: (1, 2) shareimprove this answer answered Sep 16 '16 at 16:12 Anyany Pan 35926 add a comment up vote 2 down vote pprint contains a “pretty printer” for producing aesthetically pleasing representations of your data structures. The formatter produces representations of data structures that can be parsed correctly by the interpreter, and are also easy for a human to read. The output is kept on a single line, if possible, and indented when split across multiple lines. shareimprove this answer answered Sep 13 '10 at 5:11 shahjapan 6,453145492 add a comment up vote 2 down vote This prints out all the object contents recursively in json or yaml indented format: 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) shareimprove this answer edited Mar 5 '16 at 0:33 answered Mar 4 '16 at 19:32 wisbucky 7,96834747 add a comment up vote 2 down vote Try 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) Output: __main__.A(_p = 8, foo = [0, 1, ..., 8, 9], s = 5) shareimprove this answer answered Jul 28 '16 at 7:14 Symon 363312 add a comment up vote 2 down vote Why not something simple: for key,value in obj.__dict__.iteritems(): print key,value shareimprove this answer edited Jul 28 '16 at 7:16 Paul Rooney 11.8k62442 answered Jun 14 '13 at 9:20 Michael Thamm 1096 Shouldn't that be for key,value in obj.__dict__.iteritems(): print key,value? – Raz Oct 30 '14 at 8:09 1 none of those are working for me – Tim Ogilvy Apr 16 '15 at 8:13 add a comment up vote 2 down vote I've upvoted the answer that mentions only pprint. To be clear, if you want to see all the values in a complex data structure, then do something like: from pprint import pprint pprint(my_var) Where my_var is your variable of interest. When I used pprint(vars(my_var)) I got nothing, and other answers here didn't help or the method looked unnecessarily long. By the way, in my particular case, the code I was inspecting had a dictionary of dictionaries. Worth pointing out that with some custom classes you may just end up with an unhelpful <someobject.ExampleClass object at 0x7f739267f400> kind of output. In that case, you might have to implement a __str__ method, or try some of the other solutions. I'd still like to find something simple that works in all scenarios, without third party libraries. shareimprove this answer edited Oct 9 '17 at 8:07 answered Sep 28 '17 at 4:35 Nagev 566614 >with some custom classes ... This is why I'm not a fan of python. Things "sometimes" work and "sometimes" not – AlxVallejo Dec 19 '17 at 15:09 add a comment up vote 0 down vote You can try the 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) shareimprove this answer answered Mar 7 '16 at 16:41 Slipstream 3,82112622 add a comment up vote 0 down vote I like working with python object built-in types keys or values. For attributes regardless they are methods or variables: o.keys() For values of those attributes: o.values() shareimprove this answer answered May 4 '17 at 12:53 Evhz 2,97222140 add a comment up vote 0 down vote For everybody struggling with vars() not returning all attributes. dir() not returning the attributes' values. The following code prints all attributes of obj with their values: for attr in dir(obj): try: print("obj.{} = {}".format(attr, getattr(obj, attr))) except AttributeError: print("obj.{} = ?".format(attr)) |
|||||||
Так же в этом разделе:
|
|||||||
|
|||||||
|