Is it possible to display an objects instance variables in IPython like Matlab does?

ipython, matlab, python

Solution

The short answer is that there is no way to get a list of all attributes of an object in Python, because the attributes could be generated dynamically. For an extreme example, consider this class:

>>> class Spam(object):
...     def __getattr__(self, attr):
...         if attr.startswith('x'):
...             return attr[1:]
>>> spam = Spam()
>>> spam.xeggs
'eggs'

Even if the interpreter could someone figure out a list of all attributes, that list would be infinite.

For simple classes, `spam.__dict__` is often good enough. It doesn't handle dynamic attributes, `__slots__`-based attributes, class attributes, C extension classes, attributes inherited from most of the above, and all kinds of other things. But it's at least something—and sometimes, it's the something you want. To a first approximation, it's exactly the stuff you explicitly assigned in `__init__` or later, and nothing else.

For a best effort aimed at "everything" aimed at human readability, use `dir(spam)`.

For a best effort aimed at "everything" for programmatic use, use `inspect.getmembers(spam)`. (Although in fact the implementation is just a wrapper around `dir` in CPython 2.x, it could do more—and in fact does in CPython 3.2+.)

These will both handle a wide range of things that `__dict__` cannot, and may skip things that are in the `__dict__` but that you don't want to see. But they're still inherently incomplete.

Whatever you use, to get the values as well as the keys is easy. If you're using `__dict__` or `getmembers`, it's trivial; the `__dict__` is, normally, either a `dict`, or something that acts close enough to a `dict` for your purposes, and `getmembers` explicitly returns key-value pairs. If you're using `dir`, you can get a `dict` very easily:

{key: getattr(spam, key) for key in dir(spam)}

One last thing: "object" is a bit of an ambiguous term. It can mean "any instance of a class derived from `object`", "any instance of a class", "any instance of a new-style class", or "any value of any type at all" (modules, classes, functions, etc.). You can use `dir` and `getmembers` on just about anything; the exact details of what that means are described in the docs.

One even-last-er thing: You may notice that `getmembers` returns things like `('__str__', <method-wrapper '__str__' of Spam object at 0x1066be790>`), which you probably aren't interested in. Since the results are just name-value pairs, if you just want to remove `__dunder__` methods, `_private` variables, etc., that's easy. But often, you want to filter on the "kind of member". The `getmembers` function takes a filter parameter, but the docs don't do a great job explaining how to use it (and, on top of that, expect that you understand how descriptors work). Basically, if you want a filter, it's usually `callable`, `lambda x: not callable(x)`, or a `lambda` made up of a combination of `inspect.isfoo` functions.

So, this is common enough you may want to write it up as a function:

def get_public_variables(obj):
    return [(name, value) for name, value 
            in inspect.getmembers(obj, lambda x: not callable(x))
            if not name.startswith('_')]

You can turn that into a custom IPython %magic function, or just make a %macro out of it, or just leave it as a regular function and call it explicitly.

In a comment, you asked whether you can just package this up into a `__repr__` function instead of trying to create a %magic function or whatever.

If you've already got all of your classes inheriting from a single root class, this is a great idea. You can write a single `__repr__` that works for all of your classes (or, if it works for 99% of them, you can override that `__repr__` in the other 1%), and then every time you evaluate any of your objects in the interpreter or print them out, you'll get what you want.

However, a few things to keep in mind:

Python has both `__str__` (what you get if you `print` an object) and `__repr__` (what you get if you just evaluate an object at the interactive prompt) for a reason. Usually, the former is a nice human-readable representation, while the latter is something that's either `eval`-able (or typable-into-the-interactive-prompt), or the concise angle-bracket form that gives you just enough to distinguish the type and identity of an object.

That's just a convention rather than a rule, so you can feel free to break it. However, if you are going to break it, you may still want to make use of the `str`/`repr` distinction—e.g., make `repr` give you a complete dump of all the internals, while `str` shows just the useful public values.

More seriously, you have to consider how `repr` values are composed. For example, if you `print` or `repr` a `list`, you get, effectively, `'[' + ', '.join(map(repr, item))) + ']'`. This is going to look pretty odd with a multi-line `repr`. And it'll be even worse if you use any kind of pretty-printer that tries to indent nested collections, like the one that's built into IPython. The result probably won't be unreadable, it'll just defeat the benefits that the pretty-printer is meant to provide.

As for the specific stuff you want to display: That's all pretty easy. Something like this:

def __repr__(self):
    lines = []

    classes = inspect.getmro(type(self))
    lines.append(' '.join(repr(cls) for cls in classes))

    lines.append('')
    lines.append('Attributes:')
    attributes = inspect.getmembers(self, callable)
    longest = max(len(name) for name, value in attributes)
    fmt = '{:>%s}: {}' % (longest, )
    for name, value in attributes:
        if not name.startswith('__'):
            lines.append(fmt.format(name, value))

    lines.append('')
    lines.append('Methods:')
    methods = inspect.getmembers(self, negate(callable))
    for name, value in methods:
        if not name.startswith('__'):
            lines.append(name)

    return '\n'.join(lines)

Right-justifying the attribute names is the hardest part here. (And I probably got it wrong, since this is untested code…) Everything else is either easy, or fun (playing with different filters to `getmembers` to see what they do).

Problem

I'm trying to move away from Matlab to Python. While the magic ? in IPython is nice, one very nice feature of Matlab is that you can see on the command line (by omitting the ;) the instance variables (called properties in Matlab) of the object in question. Is this possible in python (I guess via IPython)? Ideally a class like this: ``` class MyClass(object): _x = 5 @property def x(self): return self._x + 100 @x.setter def x(self, value): self._x = value + 1 def myFunction(self, y): return self.x ** 2 + y ``` Would display something like: ``` mc = Myclass() mc <package.MyClass> <superclass1> <superclass2> Attributes: _x: 5 x: 105 Method Attributes: myFunction(self, y) ``` Is that possible via overriding the print method (if such a thing exits) of the class? Or via a magic method in ipython?

Original source