Bound Python method accessed with getattr throwing:" takes no arguments (1 given) "
Question: Something rather odd is happening in an interaction between bound methods,
inheritance, and getattr that I am failing to understand.

I have a directory setup like:

    
    
    /a
    __init__.py
    start_module.py
      /b
      __init__.py
      imported_module.py 
    

imported_module.py contains a number of class objects one of which is of this
form:

    
    
    class Foo(some_parent_class):
        def bar(self):
           return [1,2,3]
    

A function in start_module.py uses inspect to get a list of strings
representing the classes in imported_module.py. "Foo" is the first of those
strings. The goal is to run bar in start_module.py using that string and
getattr.*

To do this I use code in start_module of the form:

    
    
    for class_name in class_name_list:
      instance = getattr(b.imported_module, class_name)()
      function = getattr(instance, "bar")
      for doodad in [x for x in function()]:
         print doodad 
    

Which does successfully start to iterate over the list comprehension, but on
the first string, "bar", I get a bizarre error. Despite bar being a bound
method, and so as far as I understand expecting an instance of Foo as an
argument, I am told:

TypeError: bar() takes no arguments (1 given)

This makes it seem like my call to function() is passing the Foo instance, but
the code is not expecting to receive it.

I really have no idea what is going on here and couldn't parse out an
explanation through looking on Google and Stack Overflow. Is the double
getattr causing some weird interaction? Is my understanding of class objects
in Python too hazy? I'd love to hear your thoughts.

*To avoid the anti-pattern, the real end objective is to have start_module.py automatically have access to all methods of name bar across a variety of classes similar to Foo in imported_module.py. I am doing this in the hopes of avoiding making my successors maintain a list for what could be a very large number of Foo-resembling classes. 

Answered below: I think the biggest takeaways here are that inspect is very
useful, and that if there is a common cause for the bug you are experiencing,
make absolutely sure you've ruled that out before moving on to search for
other possibilities. In this case I overlooked the fact that the module I was
looking at that had correct code might not be the one being imported due to
recent edits to the file structure.


Answer: Since the sample code you posted is wrong, I'm guessing that you have another
module with the Foo class somewhere - maybe `bar` is defined like this

    
    
    class Foo(object):
        def bar():   # <-- missing self parameter
            return [1,2,3]
    

This does give that error message

    
    
    >>> Foo().bar()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: bar() takes no arguments (1 given)
    

