Python and the self parameter
Question: I'm having some issues with the self parameter, and some seemingly
inconsistent behavior in Python is annoying me, so I figure I better ask some
people in the know. I have a class, `Foo`. This class will have a bunch of
methods, `m1`, through `mN`. For some of these, I will use a standard
definition, like in the case of `m1` below. But for others, it's more
convinient to just assign the method name directly, like I've done with `m2`
and `m3`.

    
    
    import os
    
    def myfun(x, y):
        return x + y
    
    class Foo():
        def m1(self, y, z):
            return y + z + 42
    
        m2 = os.access
        m3 = myfun
    
    f = Foo()
    print f.m1(1, 2)
    print f.m2("/", os.R_OK)
    print f.m3(3, 4)
    

Now, I know that `os.access` does not take a `self` parameter (seemingly). And
it still has no issues with this type of assignment. However, I cannot do the
same for my own modules (imagine `myfun` defined off in `mymodule.myfun`).
Running the above code yields the following output:

    
    
    3
    True
    Traceback (most recent call last):
      File "foo.py", line 16, in <module>
        print f.m3(3, 4)
    TypeError: myfun() takes exactly 2 arguments (3 given)
    

The problem is that, due to the framework I work in, I cannot avoid having a
class `Foo` at least. But I'd like to avoid having my `mymodule` stuff in a
dummy class. In order to do this, I need to do something ala

    
    
    def m3(self,a1, a2):
        return mymodule.myfun(a1,a2)
    

Which is hugely redundant when you have like 20 of them. So, the question is,
either how do I do this in a totally different and obviously much smarter way,
or how can I make my own modules behave like the built-in ones, so it does not
complain about receiving 1 argument too many.


Answer: `os.access()` is a built-in function, in the sense that it's part of an
extension module written in C. When the class is defined, Python doesn't
recognize `m2` as a method because it's the wrong type — methods are Python
functions, not C functions. `m3`, however, is a Python function, so it's
recognized as a method and handled as such.

In other words, it's `m2` that's exceptional here, not `m3`.

One simple way to do what you want would be to make `m3` a static method:

    
    
    m3 = staticmethod(myfun)
    

Now the interpreter knows never to try and pass `myfun()` a `self` parameter
when it's called as the `m3` method of a Foo object.

