Why do some object methods/attributes not show up when I call dir
on the object?
Example:
from scipy import sparse
e = sparse.eye(2)
'H' in dir(e)
returns False
. But calling e.H
works just fine (returning another sparse matrix object). Why is this so, and how can I see these hidden attributes?
I'm using Python 3.5.1.
e.H
, e.A
, e.T
are pseudo-properties of the sparse matrix object.
shape
is a property. In sparse.base.py
I find
shape = property(fget=get_shape, fset=set_shape)
while the dict
only contains:
In [121]: e.__dict__
Out[121]:
{'_shape': (2, 2),
'data': array([[ 1., 1.]]),
'format': 'dia',
'maxprint': 50,
'offsets': array([0])}
get_shape
probably accesses _shape
. set_shape
probably limits our ability to change _shape
.
I don't know of a neat way of finding all the defined properties for an object like this. Ideally they should be listed in the documentation, but sparse
documentation is not ideal.
There is an e.getH
method, which returns the same thing as e.H
, so I suspect there's a piece of code, probably in some superclass
H = property(fget=getH)
Nope - in sparse.base.py
I find a redefinition of __getattr__
, so it's an entirely different mechanism (not property and not __dict__
):
def __getattr__(self, attr):
if attr == 'A':
return self.toarray()
elif attr == 'T':
return self.transpose()
elif attr == 'H':
return self.getH()
elif attr == 'real':
return self._real()
elif attr == 'imag':
return self._imag()
elif attr == 'size':
return self.getnnz()
else:
raise AttributeError(attr + " not found")
In ipython
I can fetch this with In [152]: e.__getattr__??
or sparse.base??
.
getattr
can be used to fetch all these attributes and properties (and methods)
In [161]: getattr(e,'shape')
Out[161]: (2, 2)
In [162]: getattr(e,'_shape')
Out[162]: (2, 2)
In [163]: getattr(e,'H')
Out[163]:
<2x2 sparse matrix of type '<type 'numpy.float64'>'
with 2 stored elements in Compressed Sparse Column format>
In [164]: getattr(e,'transpose')
Out[164]:
<bound method dia_matrix.transpose of <2x2 sparse matrix of type '<type 'numpy.float64'>'
with 2 stored elements (1 diagonals) in DIAgonal format>>
With the inspect
module I can get a list of members
, e.g.
[i[0] for i in inspect.getmembers(e)]
but that still doesn't list these special ones defined in the __getattr__
method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With