One solution is to create a copy of dir before adding the __getattr__ method:
class Hal(object): def __init__(self): self._names = dir(self) def __getattr__(self, name): print self.names self.__getattr__ = __getattr__
However, for simple cases, you can simply call dir (and similarly getattr , or inspect.getmembers , or something else) in a class object to solve the problem. This does not work if the instance can have methods added after the build, but if this is not a problem, it is easy:
names = dir(self.__class__)
However, you get names to filter methods, there are a few things you need to do.
First you can use isinstance on getattr(self, name) and make sure it is a wrapper method (or get the type of the associated version and make sure it is an instance method). If you get the values โโdirectly from self.__class__.__dict__ , you wonโt get the exact same thing as if you got the names in your favorite way and call either getattr(self, name) or getattr(self.__class__, name) In particular, the instance method will display as a function , which is easier to test than the wrapper method. Although some of the other cases are now more difficult to detect.
In any case, nothing based on the type will find things that act as methods, but are not (for example, because you assigned an inline function directly to an object, wrapped something in certain kinds of decorators, descriptors, used a class with the __callable__ method as function, etc.). If you are doing something unusual (or worried that someone might add something fantastic later), you really need to check if you can explicitly bind the element (or fake it by binding to None ), and then check whether the result is callable , and then maybe do additional tests to make sure it gets called correctly (because otherwise you will be fooled by @staticmethod and other similar things). Indeed, if this happens (and you really thought through your design and convinced yourself and at least one more person that this is not crazy ...), you should check everything you can imagine against every case that you have a...
If you want to know if methods are defined in Hal or an instance, and not in an object or another base class, there are several ways to do this, but the easiest is to simply subtract the members of the base classes. (Of course, if you don't need the methods defined in the instance, Hal.__dict__ already has what you want.)