Execute Program

Python in Detail: Static Methods

Welcome to the Static Methods lesson!

This lesson is shown as static text below. However, it's designed to be used interactively. Click the button below to start!

  • The Cat class has a .name_length method. We can call it on instances of Cat.

  • >
    class Cat:
    def __init__(self, name):
    self.name = name

    def name_length(self):
    return len(self.name)

    keanu = Cat("Keanu")
    keanu.name_length()
    Result:
    5Pass Icon
  • But calling it directly on the class is a TypeError, since we don't have a self argument to pass in.

  • >
    class Cat:
    def __init__(self, name):
    self.name = name

    def name_length(self):
    return len(self.name)

    Cat.name_length()
    Result:
    TypeError: Cat.name_length() missing 1 required positional argument: 'self'Pass Icon
  • This makes sense: .name_length needs to know the cat's name, so it needs an instance of Cat to work. Normally we provide the instance by calling the method directly on it, like some_cat.name_length(). But we can also pass the instance directly to Cat.name_length.

  • >
    class Cat:
    def __init__(self, name):
    self.name = name

    def name_length(self):
    return len(self.name)

    keanu = Cat("Keanu")
    Cat.name_length(keanu)
    Result:
    5Pass Icon
  • Even when methods don't use any instance attributes, they still require the self argument. But what if we really do want a method that doesn't know about instances at all?

  • The next example adds a .species_name method. It takes self and language, and returns the species' name in the given language. Even though the method doesn't use self, we still get an exception if we don't pass it in.

  • >
    class Cat:
    def __init__(self, name):
    self.name = name

    def species_name(self, language):
    if language == "french":
    return "chat"
    else:
    return "cat"

    Cat.species_name("french")
    Result:
    TypeError: Cat.species_name() missing 1 required positional argument: 'language'Pass Icon
  • This is a good candidate for a "static method": a method that doesn't need access to the class object or any instance of the class. We create a static method by applying the @staticmethod decorator on a regular method. This works because methods are just a special kind of function, so we can wrap them with other functions.

  • >
    class Cat:
    def __init__(self, name):
    self.name = name

    @staticmethod
    def species_name(language):
    if language == "french":
    return "chat"
    else:
    return "cat"
  • This method isn't associated with any instance, so it has no self argument. We can call it directly on the class.

  • Note: this code example reuses elements (variables, etc.) defined in earlier examples.
    >
    Cat.species_name("french")
    Result:
    'chat'Pass Icon
  • For convenience, static methods are also available on instances of the class, like instances methods are.

  • Note: this code example reuses elements (variables, etc.) defined in earlier examples.
    >
    keanu = Cat("Keanu")
    keanu.species_name("en")
    Result:
    'cat'Pass Icon
  • Static methods are often used for functions that don't concern any specific instance. For example, .species_name is information about cats, but it doesn't change from cat to cat, so it's a good candidate for a static method.

  • Here's a code problem:

    The Cat class below has a convenience method that converts months to years. We want to be able to access this method on the class. To do this, make .months_to_years a static method.

    import math

    class Cat:
    def __init__(self, name, age):
    self.name = name
    self.age = age

    @staticmethod
    def months_to_years(months):
    return math.floor(months / 12)
    keanu = Cat("Keanu", 2)

    ms_fluffs_age = Cat.months_to_years(27)
    ms_fluff = Cat("Ms. Fluff", ms_fluffs_age)

    assert ms_fluff.months_to_years(27) == 2
    assert ms_fluffs_age == 2
    assert ms_fluff.age == 2
    assert ms_fluff.name == 'Ms. Fluff'
    assert keanu.name == 'Keanu'
    Goal:
    None
    Yours:
    NonePass Icon