January 15 - 18:30

I feel python's `@staticmethod`

decorator has a bad rep.
But I use it! It makes it easier to read code and distinguish where some utility functionality are being used when reading the source, especially if the person using your functionality is looking at the source or `dir`

because maybe the documentation wasn't sufficient.

A good reason to use `@staticmethod`

is that if someone wants to sub-class your work, they can override or add to the functionality of your `@staticmethod`

, which is very handy.

Let's say you've written a class that will help you calculate how many slices that are in a pizza:

```
class MyPizza(object):
def __init__(self, size, toppings):
self.size = size
self.toppings = toppings
self.pizza = {}
def _calculate_slices(self):
area = math.pi * (self.size / 2.0) * (self.size / 2.0)
return area / self.size
def bake(self):
self.pizza['slices'] = self._calculate_slices()
self.pizza['toppings'] = self.toppings
return self.pizza
```

It's all good! It'll calculate how many slices your pie should have, and bake you a pizza. Great!
A friend of yours wants one of your pizzas so you send him your glorious pizza machine, but he wants 8 slices in all his pizzas instead of a perfectly calculated amount of slices in each pie!
You could change `calculate_slices`

to always `return 8`

, not very handy though.

`@staticmethod`

to the rescue! You can use `@staticmethod`

in this case. Here's what your revised class will look like.

```
class MyPizza(object):
def __init__(self, size, toppings):
self.size = size
self.toppings = toppings
self.pizza = {}
@staticmethod
def _calculate_slices(size):
area = math.pi * (size / 2.0) * (size / 2.0)
return area / size
def bake(self):
self.pizza['slices'] = self._calculate_slices(self.size)
self.pizza['toppings'] = self.toppings
return self.pizza
```

Now your buddy can sub-class `MyPizza`

and make his own pizza machine with little effort, like so:

```
class GeoffsPizza(MyPizza):
@staticmethod
def _calculate_slices(size):
return 8
```

If you changed the method `calculate_slices`

in your original class to be a function (e.g. putting it outside of your class on the module-level) you'd have had to override the whole `bake`

method instead (well, you could've gotten around it another way, but I won't get into that solution in this post).

Here's what that would've looked like:

```
def _calculate_slices(size):
area = math.pi * (size / 2.0) * (size / 2.0)
return area / size
class MyPizza(object):
def __init__(self, size, toppings):
self.size = size
self.toppings = toppings
self.pizza = {}
def bake(self):
self.pizza['slices'] = _calculate_slices(self.size)
self.pizza['toppings'] = self.toppings
return self.pizza
```

And the sub-class:

```
class GeoffsPizza(MyPizza):
def bake(self):
self.pizza['slices'] = 8
self.pizza['toppings'] = self.toppings
return self.pizza
```

Not a great way to do it in my eyes.
Imagine if you had a much more complex `bake`

method! You'd have to copy all the logic into your sub-class and just change a few lines so the class would do what you wanted it to.

That's why I use `@staticmethod`

.