The dir(..) command can be used to obtain a list of the attributes an object holds. For instance:
$ python3
Python 3.5.2 (default, Nov 17 2016, 17:05:23)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy as np
>>> dir(np)
['ALLOW_THREADS', 'BUFSIZE', 'CLIP', 'ComplexWarning', 'DataSource', 'ERR_CALL', 'ERR_DEFAULT', 'ERR_IGNORE', 'ERR_LOG', 'ERR_PRINT', 'ERR_RAISE', 'ERR_WARN', 'FLOATING_POINT_SUPPORT', 'FPE_DIVIDEBYZERO', 'FPE_INVALID', 'FPE_OVERFLOW', 'FPE_UNDERFLOW',..., 'var', 'vdot', 'vectorize', 'version', 'void', 'void0', 'vsplit', 'vstack', 'warnings', 'where', 'who', 'zeros', 'zeros_like']
(the output is cutted to make it easier to fetch and format it).
It returns a list of strings that show what is in an object. Note that this function can also be used to program in Python as well: you could for instance iterate over it, filter for a certain pattern and copy these attributes to another object. For instance you could write a copy_fields function:
def copy_fields(frm,to):
for attr in dir(frm):
setattr(to,atr,getattr(frm,atr))
Here getattr(..) and setattr(..) are function that given an object (frm and to) and the name of an attribute (attr) respectively get and set that attribute.
I'm quite confident that this is what happens (more or less) behind the curtains of ipython (although probably ipython also aims to derive the type such that it can write a parenthesis (() for functions, etc.
Finally mind that dir(..) can't always report all attributes (since sometimes attributes can be processed by functions resulting in the fact that an object has "virtually" an infinite amount of attributes; that is for instance the case for objects in BeautifulSoup where, if the attribute is not a standardized one, BeautifulSoup sees it as a query). Behind the curtains dir(..) works as follows:
If the object has a method named __dir__(), this method will be called
and must return the list of attributes. This allows objects that
implement a custom __getattr__() or __getattribute__() function to
customize the way dir() reports their attributes.
If the object does not provide __dir__(), the function tries its best
to gather information from the object’s __dict__ attribute, if
defined, and from its type object. The resulting list is not
necessarily complete, and may be inaccurate when the object has a
custom __getattr__().
(source)