@staticmethod called outside class scope (?)

Hello,

I have a beginner question about the decorator @staticmethod. In docummentation (for Python, v. 3.10 [it is an added line for this version]), I read:
“Moreover, they can be called as regular functions (such as f() ).”

Does it mean that this should work? It seems that it should not (because it doesn’t work).

class C:
    @staticmethod
    def f():
        print("Hi!")

f()

Does it mean that this ability is limited only to the scope of the class?

In the docummentation, there is also information about all decorators being callable as a regular function in this way:

def regular_function():
    ...

class C:
    method = staticmethod(regular_function)

That is confusing… What is the special ability of @staticmethod to be called as regular function then (there is no such line in section of @classmethod)?

Thank you for the clarification and help! :slightly_smiling_face:

You still need to access the method as C.f. “Outside of class scope” is a confusing way to describe it.

The special behavior is that the static method is just a function, and does not have any special parameter special binding behavior like class methods and instance methods.

1 Like

Also, to note, if you’re using a @staticmethod, its generally simpler and more Python to simply make it a regular function instead, since its simpler and more Pythonic, and otherwise no different from a practical perspective—@staticmethod is mostly included as a convenience for those used to that pattern from other, strictly OOP language (cough, Java, cough).

2 Likes

Thank you very much for your help! :slight_smile:

What the documentation means is that the static method can be used as a function inside the class, like this:

class C:
    @staticmethod
    def f():
        return "Hello world"

    # Okay to call f() inside the class.
    attribute = f()


assert C.attribute == "Hello world"

Until Python 3.10, that would not work, as staticmethods were not directly callable unless they were accessed through the class C or an instance. But in Python 3.10, they were enhanced to be callable directly, so now all of these do the same thing:

# Access through the class.
C.f()

# Access through an instance.
obj = C()
obj.f()

# Bypass dot access and call the raw staticmethod.
raw_obj = vars(C)['f']
raw_obj()

In Python 3.9 and older, only the first two calls would work, not the third.

1 Like