Skip to content
Advertisement

Is there any difference between using a decorator and applying the function directly?

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.

Advertisement

Answer

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__).

User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement