I recently became the maintainter of PyPDF2 - a library which is pretty old and still has some code that deals with Python versions before 2.4. While I want to drop support for 3.5 and older soon, I see some parts where I'm uncertain why they were written as they are.
One example is this:
What is in the code:
class Foo(object):
def a(b, c):
print(b)
print(c)
a = staticmethod(a)
What I would expect instead:
class Bar(object):
@staticmethod
def a(b, c):
print(b)
print(c)
Is there any reason to use the first notation? Are they strictly equivalent?
I've seen that decorators were introduced in Python 2.4, so this might be an example of such extreme legacy code.
The first version is just the pre-2.4 way to use staticmethod
. The two versions aren't quite equivalent, but the difference is so tiny it almost never matters.
Specifically, on Python versions that support decorator syntax, the one difference is that the second version passes the original function directly to staticmethod
, while the first version stores the original function to a
and then looks up the a
variable to find the argument to pass to staticmethod
. This can technically matter in very weird use cases, particularly with metaclasses, but it'd be highly unlikely. Python 2 doesn't even support the relevant metaclass feature (__prepare__
).