Python How can I request a class that defines a method?

My question is somewhat similar to this ; this concerns object methods, not the content of modules. I want to know if I can use the inspect module to get methods defined only in the class I am asking about, not its parent.

I need this because my child class defines macro methods that access the parent methods at a higher level of abstraction, and I don’t want the user to have to worry about the lower level methods defined all the way up the inheritance tree.

Here is a simplified example:

 class Foo(object): def __init__(self): pass def f1(self): return 3 def f2(self): return 1 class Bar(Foo): def __init__(self): Foo.__init__(self) def g1(self): return self.f1() + self.f2() def g2(self): return self.f1() - self.f2() import inspect inspect.getmembers(Bar, inspect.ismethod) 

Output:

 [('__init__', <unbound method Bar.__init__>), ('f1', <unbound method Bar.f1>), ('f2', <unbound method Bar.f2>), ('g1', <unbound method Bar.g1>), ('g2', <unbound method Bar.g2>)] 

The user does not need to know or care about the existence of f , since she will only be interested in g s. (Of course, this conclusion makes sense in the vast majority of contexts, since all these methods will be tied to the object when it is created.) For a long inheritance tree, the returned list can get a lot of time and things, pertaining to the user.

How can I make it leave f1 and f2 in this list? Is there an equivalent to the __module__ attribute for methods defined in classes? Even better is it possible to do the same with instance methods?

+2
python methods introspection
Aug 13 2018-12-12T00:
source share
2 answers

Methods have an im_class attribute that points to the corresponding class. You can use this filter for functions included in the class:

 inspect.getmembers(Bar, lambda m: inspect.ismethod(m) and m.__func__ in m.im_class.__dict__.values()) 

This gives you:

 [ ('__init__', <unbound method Bar.__init__>), ('f1', <unbound method Bar.f1>), ('f2', <unbound method Bar.f2>) ] 

Of course, you can just get around getmembers in general:

 [m for m in Bar.__dict__.values() if inspect.isfunction(m)] 

gives:

 [<function __init__ at 0x100a28de8>, <function g1 at 0x100a28e60>, <function g2 at 0x100a28ed8>] 

This applies to related or unrelated methods, they have the same attribute .__func__ (or im_func , old name). The difference between bound and unbound is the value of the .__self__ attribute (None when unbound).

These "secret" attributes are described in the Python Data Model .

+5
Aug 13 2018-12-12T00:
source share
β€” -

Hope someone comes along with a better solution, but what about:

 foo_members = inspect.getmembers(Foo,inspect.ismethod) bar_members = inspect.getmembers(Bar,inspect.ismethod) set(bar_members) - set(foo_members) 

Of course, in a real situation, you may need to go through Bar.__bases__ to actually get rid of everything you don't need.

eg:.

 set(bar_members) - set(sum([inspect.getmembers(base,inspect.ismethod) for base in Bar.__bases__],[])) 
+2
Aug 13 2018-12-12T00:
source share



All Articles