Search code examples
pythonpython-3.xtypeerrorself

Why is `self` not used in this method?


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) 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.


Solution

  • 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()