By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,813 Members | 1,236 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,813 IT Pros & Developers. It's quick & easy.

Finding the public callables of self

P: n/a
Is there any better way to get a list of the public callables of self
other than this?

myCallables = []
classDir = dir(self)
for s in classDir:
attr = self.__getattribute__(s)
if callable(attr) and (not s.startswith("_")):
myCallables.append(s) #collect the names (not funcs)

I don't mean a shorter list comprehension or something that just drops
the line count, but whether or not I need to go at it through dir and
__getattribute__. This seems a bit convoluted and with python it often
seems there's something already canned to do stuff like this when I do
it. At first I thought self.__dict__ would do it, but callable methods
seem to be excluded so I had to resort to dir, and deal with the
strings it gives me.

Thanks,
Russ

Feb 9 '06 #1
Share this Question
Share on Google+
6 Replies


P: n/a
import inspect
myCallables = [name for name, value in inspect.getmembers(self) if not
name.startswith('_') and callable(value)]
Instance methods aren't in self.__dict__ because they're a part of the
class. To made a comprehensive list of all the attributes available to
an instance, you have to traverse the attribute dictionaries of the
instance, its class, and all of the base classes in the right order.
(inspect.getmro returns the base classes in method resolution order)

Feb 9 '06 #2

P: n/a
Russell Warren wrote:
Is there any better way to get a list of the public callables of self
other than this?

myCallables = []
classDir = dir(self)
for s in classDir:
attr = self.__getattribute__(s)
if callable(attr) and (not s.startswith("_")):
myCallables.append(s) #collect the names (not funcs)
I don't mean a shorter list comprehension or something that just drops
the line count, but whether or not I need to go at it through dir and
__getattribute__. This seems a bit convoluted and with python it often
seems there's something already canned to do stuff like this when I do
it.
Use getattr(self, s) instead of self.__getattribute__(s).

You could streamline it a bit with a list comprehension:
myCallables = [ s for s in dir(self) if not s.startswith('_') and
callable(getattr(self, s)) ]

At first I thought self.__dict__ would do it, but callable methods seem to be excluded so I had to resort to dir, and deal with the
strings it gives me.


The callables are attributes of the class and its base classes, not of
self. self.__dict__ just contains instance attributes.

Kent
Feb 9 '06 #3

P: n/a
Russell Warren <ru************@gmail.com> wrote:
Is there any better way to get a list of the public callables of self
other than this?

myCallables = []
classDir = dir(self)
for s in classDir:
attr = self.__getattribute__(s)
if callable(attr) and (not s.startswith("_")):
myCallables.append(s) #collect the names (not funcs)

I don't mean a shorter list comprehension or something that just drops
the line count, but whether or not I need to go at it through dir and
__getattribute__. This seems a bit convoluted and with python it often
seems there's something already canned to do stuff like this when I do
it. At first I thought self.__dict__ would do it, but callable methods
seem to be excluded so I had to resort to dir, and deal with the
strings it gives me.


This last sentence suggests to me something like:

attrs = set(s for s in dir(self) if not s.startswith('_'))
myCallables = attrs.difference(a.__dict__)
return list(myCallables)

(which you can get down to one line if you want).

--
\S -- si***@chiark.greenend.org.uk -- http://www.chaos.org.uk/~sion/
___ | "Frankly I have no feelings towards penguins one way or the other"
\X/ | -- Arthur C. Clarke
her nu becomež se bera eadward ofdun hlęddre heafdes bęce bump bump bump
Feb 9 '06 #4

P: n/a
Sion Arrowsmith wrote:
Russell Warren <ru************@gmail.com> wrote: (snip) At first I thought self.__dict__ would do it, but callable methods
seem to be excluded so I had to resort to dir, and deal with the
strings it gives me.
This last sentence suggests to me something like:

attrs = set(s for s in dir(self) if not s.startswith('_'))
myCallables = attrs.difference(a.__dict__)

err... s/a.__dict__/self.__dict__/
return list(myCallables)

Won't work as expected:
class Tricky(object): .... class_attrib = 42
.... def __init__(self, attr):
.... self.attr = attr
.... def doit(self):
.... if callable(self.attr):
.... return self.attr(self)
.... t = Tricky(lambda obj: obj.__class__.__name__)
t <__main__.Tricky object at 0x2aaaaab28ed0> def getcallables(obj): .... attrs = set(s for s in dir(obj) if not s.startswith('_'))
.... callables = attrs.difference(obj.__dict__)
.... return list(callables)
.... getcallables(t) ['doit', 'class_attrib'] t.attr(t) 'Tricky' t.class_attrib()

Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: 'int' object is not callable
There are 2 reliable ways to know if an object is callable:
- using callable()
- trying to call it
--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom.gro'.split('@')])"
Feb 9 '06 #5

P: n/a
> import inspect
myCallables = [name for name, value in inspect.getmembers(self) if not
name.startswith('_') and callable(value)]


Thanks. I forgot about the inspect module. Interestingly, you've also
answered my question more than I suspect you know! Check out the code
for inspect.getmembers():

def getmembers(object, predicate=None):
"""Return all members of an object as (name, value) pairs sorted by
name.
Optionally, only return members that satisfy a given predicate."""
results = []
for key in dir(object):
value = getattr(object, key)
if not predicate or predicate(value):
results.append((key, value))
results.sort()
return results

Seems familiar! The fact that this is using dir(), getattr(), and
callable() seems to tell me there is no better way to do it. I guess
my method wasn't as indirect as I thought!

And thanks for the reminder about getattr() instead of
__getattribute__() and other streamlining tips.

Russ

Feb 9 '06 #6

P: n/a
Ha! I didn't realize that was getmembers' implementation. What a hack
;-)

In fact, your way is faster, since getmembers is taking the time to
sort its results (presumably so that repeated calls to the same object
will yield the same list; I don't think dir has a guaranteed ordering)

Feb 9 '06 #7

This discussion thread is closed

Replies have been disabled for this discussion.