What magic does staticmethod() do, so that the static method is always called without the instance parameter?
Question: I am trying to understand how static methods work internally. I know how to
use `@staticmethod` decorator but I will be avoiding its use in this post in
order to dive deeper into how static methods work and ask my questions.

From what I know about Python, if there is a class `A`, then calling `A.foo()`
calls `foo()` with no arguments whereas calling `A().foo()` calls `foo()` with
one argument where that one argument is the instance `A()` itself.

However, in case of static methods, it seems always `foo()` is called with no
arguments whether we call it as `A.foo()` or `A().foo()`.

Proof below:

    
    
    >>> class A:
    ...     x = 'hi'
    ...     def foo():
    ...         print('hello, world')
    ...     bar = staticmethod(foo)
    ...
    >>> A.bar()
    hello, world
    >>> A().bar()
    hello, world
    >>> A.bar
    <function A.foo at 0x00000000005927B8>
    >>> A().bar
    <function A.foo at 0x00000000005927B8>
    >>> A.bar(1)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: foo() takes 0 positional arguments but 1 was given
    >>> A().bar(1)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: foo() takes 0 positional arguments but 1 was given
    

So am I right in concluding that the `staticmethod()` function does some magic
such that `foo()` is always called with 0 arguments?

If I were to define my own `staticmethod()` in my own Python code, how would I
do it? Is it even possible to define such a method from our own Python code,
or can such a function be only defined as a builtin?


Answer: It's implemented as a
[descriptor](http://docs.python.org/2/howto/descriptor.html#definition-and-
introduction). For example:

    
    
    In [1]: class MyStaticMethod(object):
       ...:     def __init__(self, func):
       ...:         self._func = func
       ...:     def __get__(self, inst, cls):
       ...:         return self._func
       ...:     
    
    In [2]: class A(object):
       ...:     @MyStaticMethod
       ...:     def foo():
       ...:         print('Hello, World!')
       ...:         
    
    In [3]: A.foo()
    Hello, World!
    
    In [4]: A().foo()
    Hello, World!
    

In the same way you can define `classmethod`, just passing the `cls` to the
original function:

    
    
    In [5]: from functools import partial
       ...: 
       ...: class MyClassMethod(object):
       ...:     def __init__(self, func):
       ...:         self._func = func
       ...:     def __get__(self, inst, cls):
       ...:         return partial(self._func, cls)
    
    In [6]: class A(object):
       ...:     @MyClassMethod
       ...:     def foo(cls):
       ...:         print('In class: {}'.format(cls))
       ...:         
    
    In [7]: A.foo()
    In class: <class '__main__.A'>
    
    In [8]: A().foo()
    In class: <class '__main__.A'>
    

