Reputation: 15746
I am working with a 3rd party library that I am new to. There's a method that I'm trying to call, but I can't find it. It's in self
... somewhere. It could be on a child attribute or on a child of a child, or on a child of a child of a child -- deep down in self
. But I can't find it. It's a large tree, so finding this is taking a long time.
How do I find it?
This is a generic problem. It can happen to anyone when learning a new library, especially a complex one, for the first time. We all know to RTFM, but sometimes that isn't enough. If we have access to the source, we can read the source. But, if the library is complex, heavily decorated, wrapped, re-factored, SOLID principle'd library, the above might not be very fruitful.
I've tried to mess with vars()
, dir()
and the inspect
module, but so far no good. I'm probably using them wrong.
Upvotes: 2
Views: 74
Reputation: 13110
Here is some hackish code which recursively crawls through the attributes of an object, looking for any attribute with a given name.
In the example, the numpy
package is searched for any attribute with the name normal
.
Edit: The code now also search in superclasses.
import numpy
# Hackish function doing the recursive attribute search
def find_attr(object_name, attr_name):
matches = []
def f(a, search, names=None, objects=None):
if not hasattr(a, '__dict__'):
return
if names is None:
names = []
objects = []
for varname, var in vars(a).items():
if varname in names:
if var in objects:
continue
if varname == search:
matches.append(object_name + '.' + varname1 + '.' + '.'.join(names + [varname]))
result = f(var, search, names + [varname], objects + [var])
mother_obj = eval(object_name)
for varname1 in dir(mother_obj):
if varname1 == attr_name:
matches.append(object_name + '.' + varname1)
try:
var = getattr(mother_obj, varname1)
except AttributeError:
continue
f(var, attr_name)
return sorted(matches, key=len)
# Define your search
object_name = 'numpy'
attr_name = 'normal'
# Do the search
matches = find_attr(object_name, attr_name)
print('\n'.join(matches))
This gives me 1240 results, the first one being numpy.random.normal
.
Note that the search can take some time to complete when searching through a deep object like this. The above example takes 2 minutes on my computer.
Upvotes: 1