Why is `self` not used in this method?
Question: I was under the impression that methods within Python classes _always_ require
the `self` argument (I know that it doesn't actually have to be `self`, just
some keyword). But, this class that I wrote doesn't require it:

    
    
    import ZipFile
    import os
    class Zipper:
        def make_archive(dir_to_zip):
            zf = zipfile.ZipFile(dir_to_zip + '.zip', 'w')
            for filename in files:
                zf.write(os.path.join(dirname, filename))
            zf.close()
    

See? No `self`. When I include a `self` argument to `make_archive`, I get a
`TypeError: make_archive() missing one positional argument` error. In my
search to figure out why this is happening, I actually copied and tried to run
a similar program from the docs:

    
    
    class MyClass:
        """A simple example class"""
        i = 12345
    
        def f(self):
            return 'hello world'
    
    print(MyClass.f())  # I added this statement to have a call line
    

and I get the same error!

    
    
    TypeError: f() missing 1 required positional argument: 'self'
    

In the same module that contains the `Zipper()` class, I have multiple classes
that all make use of `self`. I don't understand the theory here, which makes
it difficult to know when to do what, especially since a program copied
directly from the docs ([this is the docs
page](https://docs.python.org/3/tutorial/classes.html)) failed when I ran it.
I'm using Python 3.5 and 3.4 on Debian Linux. The only thing that I can think
of is that it's a static method (and the `Zipper.make_archive()` as written
above works fine if you include `@staticmethod` above the `make_archive`
method), but I can't find a good explanation to be sure.


Answer: You are trying to use it as a static method. In your example;

    
    
    class MyClass:
        """A simple example class"""
        i = 12345
    
        def f(self):
           return 'hello world'
    
    a = MyClass()
    a.f()  # This should work.
    

Calling `MyClass.f()` assumes `f` is static for `MyClass`. You can make it
static as:

    
    
    class MyClass:
        @staticmethod
        def f():  # No self here
           return 'hello world'
    
    MyClass.f()
    

