What is the Python equivalent of Ruby's "inspect"? - python

I just want to quickly see the properties and values of an object in Python, how do I do that in the terminal on a mac (very basic stuff, never used python)?
Specifically, I want to see what message.attachments are in this Google App Engine MailHandler example (images, videos, docs, etc.).

If you want to dump the entire object, you can use the pprint module to get a pretty-printed version of it.
from pprint import pprint
pprint(my_object)
# If there are many levels of recursion, and you don't want to see them all
# you can use the depth parameter to limit how many levels it goes down
pprint(my_object, depth=2)
Edit: I may have misread what you meant by 'object' - if you're wanting to look at class instances, as opposed to basic data structures like dicts, you may want to look at the inspect module instead.

use the getmembers attribute of the inspect module
It will return a list of (key, value) tuples. It gets the value from obj.__dict__ if available and uses getattr if the the there is no corresponding entry in obj.__dict__. It can save you from writing a few lines of code for this purpose.

Update
There are better ways to do this than dir. See other answers.
Original Answer
Use the built in function dir(fp) to see the attributes of fp.

I'm surprised no one else has mentioned Python's __str__ method, which provides a string representation of an object. Unfortunately, it doesn't seem to print automatically in pdb.
One can also use __repr__ for that, but __repr__ has other requirements: for one thing, you are (at least in theory) supposed to be able to eval() the output of __repr__, though that requirement seems to be enforced only rarely.

Try
repr(obj) # returns a printable representation of the given object
or
dir(obj) # the list of object methods
or
obj.__dict__ # object variables

Or unify Abrer and Mazur answers and get:
from pprint import pprint
pprint(my_object.__dict__ )

Related

How to tell which type annotations support __iter__

If I parse the ast of a Python file and see that a variable has a type annotation, e.g. Mapping, how can I tell if that annotation supports __iter__?
One option would be to look through https://mypy.readthedocs.io/en/stable/protocols.html , make a list of everything which supports __iter__ (e.g. Iterable, Iterator, Collection, ...), and check if a given variable's annotation is in that list.
But, this feels brittle - is there a better way? I need to be able to do this just by parsing a variable's annotation from its ast - running iter on a variable isn't an option.
The simplest way is to resolve the FQN of the given annotation, and then retrieve the stub for the module it belongs to (e.g typing.pyi from typeshed) and then recursively decypher all the methods that class implements and check whether it implements the protocols you want it to do. Obviously this is a complicated procedure, so if you want to make stuff easier instead of parsing and partially evaluating module stubs, you can try to import to module dynamically and then do a simple issubclass check.

Attributes which aren't valid python identifiers

The usual method of attribute access requires attribute names to be valid python identifiers.
But attributes don't have to be valid python identifiers:
>>> class Thing:
... def __init__(self):
... setattr(self, '0potato', 123)
...
>>> t = Thing()
>>> Thing.__getattribute__(t, '0potato')
123
>>> getattr(t, '0potato')
123
Of course, t.0potato remains a SyntaxError, but the attribute is there nonetheless:
>>> vars(t)
{'0potato': 123}
What is the reason for this being permissable? Is there really any valid use-case for attributes with spaces, empty string, python reserved keywords etc? I thought the reason was that attributes were just keys in the object/namespace dict, but this makes no sense because other objects which are valid dict keys are not allowed:
>>> setattr(t, ('tuple',), 321)
TypeError: attribute name must be string, not 'tuple'
The details from a comment on the post fully answer this question, so I'm posting it as an answer:
Guido says:
...it is a feature that you can use any arbitrary string
with getattr() and setattr(). However these functions should (and do!)
reject non-strings.
Possible use-cases include hiding attributes from regular dotted access, and making attributes in correspondence with external data sources (which may clash with Python keywords). So, the argument seems to be there's simply no good reason to forbid it.
As for a reason to disallow non-strings, this seems to be a sensible restriction which is ensuring greater performance of the implementation:
Although Python's dicts already have some string-only optimizations -- they just dynamically adapt to a more generic and slightly slower approach once the first non-key string shows up.
So, to answer the use case question, looking at the reasoning behind how Python works in the references from the comments above, we can infer some of the situations that might make this Pythonic quirk useful.
You want an object to have an attribute that cannot be accessed with dot notation, say, to protect it from the naive user. (Quoting Guido: "some people might use this to hide state they don't want accessible using regular attribute notation (x.foo)". Of course, he goes on to say, "but that feels like abuse of the namespace to me, and there are plenty of other
ways to manage such state.")
You want an object's attribute names to correspond to external data over which you have no control. Thus, you have to be able to use whatever strings appear in the external data as an attribute name even if it matches a Python reserved word or contains embedded spaces or dashes, etc.

Can Python method check if it's being used for assignment?

Suppose I have a method which can return a value, or can just be quickly called to see if I even did get the return value I expected.
from pprint import pprint
from my_module import get_data
def quicktest():
#pseudocode here to illustrate what I want
if isUsedForAssignment:
return get_data()
else:
pprint(get_data())
The idea here being I'm checking this returned data to ensure the structure is correct; however if I don't care about that, I'd rather assign the value. This way I just go into my Python interpreter and type:
import thismodule as thism
thism.quicktest()
…as opposed to some way of doing it where I'm continually importing pprint just to see my data structure correctly.
This is maybe a slightly pedantic example, but it prompted the question in me as to whether or not a method can tell if it's being used to assign a value or just to be called straight-up.
Technically you could inspect the parent frame's bytecode or source code. But this is not only incredibly fragile and hacky and complicated, it's also a surefire way to indicate that you're doing something wrongTM. Just don't do that. Write the method to always simply return the value, and do the printing at the call site. Alternatively, if the printing is nontrivial, write a separate method to do the printing.

GetAttr Function Problems (Python 3)

I have the following in a Python script:
setattr(stringRESULTS, "b", b)
Which gives me the following error:
AttributeError: 'str' object has no attribute 'b'
Can any-one telling me what the problem is here?
Don't do this. To quote the inestimable Greg Hewgill,
"If you ever find yourself using quoted names to refer to variables,
there's usually a better way to do whatever you're trying to do."
[Here you're one level up and using a string variable for the name, but it's the same underlying issue.] Or as S. Lott followed up with in the same thread:
"90% of the time, you should be using a dictionary. The other 10% of
the time, you need to stop what you're doing entirely."
If you're using the contents of stringRESULTS as a pointer to some object fred which you want to setattr, then these objects you want to target must already exist somewhere, and a dictionary is the natural data structure to store them. In fact, depending on your use case, you might be able to use dictionary key/value pairs instead of attributes in the first place.
IOW, my version of what (I'm guessing) you're trying to do would probably look like
d[stringRESULTS].b = b
or
d[stringRESULTS]["b"] = b
depending on whether I wanted/needed to work with an object instance or a dictionary would suffice.
(P.S. relatively few people subscribe to the python-3.x tag. You'll usually get more attention by adding the bare 'python' tag as well.)
Since str is a low-level primitive type, you can't really set any arbitrary attribute on it. You probably need either a dict or a subclass of str:
class StringResult(str):
pass
which should behave as you expect:
my_string_result = StringResult("spam_and_eggs")
my_string_result.b = b
EDIT:
If you're trying to do what DSM suggests, ie. modify a property on a variable that has the same name as the value of the stringRESULTS variable then this should do the trick:
locals()[stringRESULTS].b = b
Please note that this is an extremely dangerous operation and can wreak all kinds of havoc on your app if you aren't careful.

best way to implement custom pretty-printers

Customizing pprint.PrettyPrinter
The documentation for the pprint module mentions that the method PrettyPrinter.format is intended to make it possible to customize formatting.
I gather that it's possible to override this method in a subclass, but this doesn't seem to provide a way to have the base class methods apply line wrapping and indentation.
Am I missing something here?
Is there a better way to do this (e.g. another module)?
Alternatives?
I've checked out the pretty module, which looks interesting, but doesn't seem to provide a way to customize formatting of classes from other modules without modifying those modules.
I think what I'm looking for is something that would allow me to provide a mapping of types (or maybe functions) that identify types to routines that process a node. The routines that process a node would take a node and return the string representation it, along with a list of child nodes. And so on.
Why I’m looking into pretty-printing
My end goal is to compactly print custom-formatted sections of a DocBook-formatted xml.etree.ElementTree.
(I was surprised to not find more Python support for DocBook. Maybe I missed something there.)
I built some basic functionality into a client called xmlearn that uses lxml. For example, to dump a Docbook file, you could:
xmlearn -i docbook_file.xml dump -f docbook -r book
It's pretty half-ass, but it got me the info I was looking for.
xmlearn has other features too, like the ability to build a graph image and do dumps showing the relationships between tags in an XML document. These are pretty much totally unrelated to this question.
You can also perform a dump to an arbitrary depth, or specify an XPath as a set of starting points. The XPath stuff sort of obsoleted the docbook-specific format, so that isn't really well-developed.
This still isn't really an answer for the question. I'm still hoping that there's a readily customizable pretty printer out there somewhere.
My solution was to replace pprint.PrettyPrinter with a simple wrapper that formats any floats it finds before calling the original printer.
from __future__ import division
import pprint
if not hasattr(pprint,'old_printer'):
pprint.old_printer=pprint.PrettyPrinter
class MyPrettyPrinter(pprint.old_printer):
def _format(self,obj,*args,**kwargs):
if isinstance(obj,float):
obj=round(obj,4)
return pprint.old_printer._format(self,obj,*args,**kwargs)
pprint.PrettyPrinter=MyPrettyPrinter
def pp(obj):
pprint.pprint(obj)
if __name__=='__main__':
x=[1,2,4,6,457,3,8,3,4]
x=[_/17 for _ in x]
pp(x)
This question may be a duplicate of:
Any way to properly pretty-print ordered dictionaries in Python?
Using pprint.PrettyPrinter
I looked through the source of pprint. It seems to suggest that, in order to enhance pprint(), you’d need to:
subclass PrettyPrinter
override _format()
test for issubclass(),
and (if it's not your class), pass back to _format()
Alternative
I think a better approach would be just to have your own pprint(), which defers to pprint.pformat when it doesn't know what's up.
For example:
'''Extending pprint'''
from pprint import pformat
class CrazyClass: pass
def prettyformat(obj):
if isinstance(obj, CrazyClass):
return "^CrazyFoSho^"
else:
return pformat(obj)
def prettyp(obj):
print(prettyformat(obj))
# test
prettyp([1]*100)
prettyp(CrazyClass())
The big upside here is that you don't depend on pprint internals. It’s explicit and concise.
The downside is that you’ll have to take care of indentation manually.
If you would like to modify the default pretty printer without subclassing, you can use the internal _dispatch table on the pprint.PrettyPrinter class. You can see how examples of how dispatching is added for internal types like dictionaries and lists in the source.
Here is how I added a custom pretty printer for MatchPy's Operation type:
import pprint
import matchpy
def _pprint_operation(self, object, stream, indent, allowance, context, level):
"""
Modified from pprint dict https://github.com/python/cpython/blob/3.7/Lib/pprint.py#L194
"""
operands = object.operands
if not operands:
stream.write(repr(object))
return
cls = object.__class__
stream.write(cls.__name__ + "(")
self._format_items(
operands, stream, indent + len(cls.__name__), allowance + 1, context, level
)
stream.write(")")
pprint.PrettyPrinter._dispatch[matchpy.Operation.__repr__] = _pprint_operation
Now if I use pprint.pprint on any object that has the same __repr__ as matchpy.Operation, it will use this method to pretty print it. This works on subclasses as well, as long as they don't override the __repr__, which makes some sense! If you have the same __repr__ you have the same pretty printing behavior.
Here is an example of the pretty printing some MatchPy operations now:
ReshapeVector(Vector(Scalar('1')),
Vector(Index(Vector(Scalar('0')),
If(Scalar('True'),
Scalar("ReshapeVector(Vector(Scalar('2'), Scalar('2')), Iota(Scalar('10')))"),
Scalar("ReshapeVector(Vector(Scalar('2'), Scalar('2')), Ravel(Iota(Scalar('10'))))")))))
Consider using the pretty module:
http://pypi.python.org/pypi/pretty/0.1

Categories

Resources