Why isn't "self" used in this method?

I was under the impression that methods in Python classes always require an argument self

(I know it really shouldn't be self

, just some kind of keyword). But this class I wrote doesn't require this:

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

      

Cm? No self

. When I include the argument self

in make_archive

, I get an error TypeError: make_archive() missing one positional argument

. 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 am getting the same error!

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

      

In the same module that contains the class Zipper()

, I have several classes that use self

. I don't understand the theory here, which makes it difficult to figure out what to do, especially since the program copied directly from the documents ( this is the docs page ) failed when I ran it. I am using Python 3.5 and 3.4 on Debian Linux. The only thing I can think of is that this is a static method (and Zipper.make_archive()

, as written above, works great if you include the @staticmethod

above method make_archive

), but I can't find a good explanation for sure.

+1


source to share


2 answers


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.

      



The call MyClass.f()

assumes that it f

is static for MyClass

. You can make it static like:

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

MyClass.f()

      

0


source


The thing with self

is that it's added implicitly. That is, the calling code speaks Myclass().f()

, but the callee sees Myclass().f(self)

. This also means that the method is called from some instance Myclass

, which is placed in a variable self

. The point is, the methods probably use and / or modify the instance data in some way (otherwise, why would they be in this class?), And this is handy for automatically providing an instance.

If you don't need instance data, you should use either @staticmethod

if it looks more like a function than an object method, or @classmethod

if the method is intended to be inherited and possibly used differently by different classes. See @ pankaj-daga's answer for a little introduction to staticmethods.



The syntax is Foo.bar()

also used by functions imported via import Foo

instead from Foo import bar

, which is also a possible source of confusion. This, for your purposes, is a completely different matter.

0


source







All Articles