The @staticmethod
decorator is nothing new. In fact, it was added in version 2.2. However, it's not till now in 2012 that I have genuinely fallen in love with it.
First a quick recap to remind you how @staticmethod
works.
class Printer(object):
def __init__(self, text):
self.text = text
@staticmethod
def newlines(s):
return s.replace('\n','\r')
def printer(self):
return self.newlines(self.text)
p = Printer('\n\r')
assert p.printer() == '\r\r'
So, it's a function that has nothing to do with the instance but still belongs to the class. It belongs to the class from an structural point of view of the observer. Like, clearly the newlines
function is related to the Printer
class. The alternative is:
def newlines(s):
return s.replace('\n','\r')
class Printer(object):
def __init__(self, text):
self.text = text
def printer(self):
return newlines(self.text)
p = Printer('\n\r')
assert p.printer() == '\r\r'
It's the exact same thing and one could argue that the function has nothing to do with the Printer
class. But ask yourself (by looking at your code); how many times do you have classes with methods on them that take self
as a parameter but never actually use it?
So, now for the trump card that makes it worth the effort of making it a staticmethod
: object orientation. How would you do this neatly without OO?
class UNIXPrinter(Printer):
@staticmethod
def newlines(s):
return s.replace('\n\r', '\n')
p = UNIXPrinter('\n\r')
assert p.printer() == '\n'
Can you see it? It's ideal for little functions that should be domesticated by the class but have nothing to do with the instance (e.g. self
). I used to think it looked like it's making a pure looking thing like something more complex that it needs to be. But now, I think it looks great!