3

Let's say I have a class and would like to implement a method which creates an instance of that class. What I have is 2 options:

  1. static method,
  2. class method.

An example:

class DummyClass:
    def __init__(self, json):
        self.dict = json
    
    @staticmethod
    def from_json_static(json):
        return DummyClass(json)

    @classmethod
    def from_json_class(cls, json):
        return cls(json)

Both of the methods work:

dummy_dict = {"dummy_var": 124}
dummy_instance = DummyClass({"test": "abc"})

dummy_instance_from_static = dummy_instance.from_json_static(dummy_dict)
print(dummy_instance_from_static.dict)
> {'dummy_var': 124}

dummy_instance_from_class = DummyClass.from_json_class(dummy_dict)
print(dummy_instance_from_class.dict)
> {'dummy_var': 124}

What I often see in codes of other people is the classmethod design instead of staticmethod. Why is this the case?

Or, rephrasing the question to possibly get a more comprehensive answer: what are the pros and cons of creating a class instance via classmethod vs staticmethod in Python?

3
  • 1
    The @classmethod approach creates an object of the right type if invoked on a subclass, rather than on DummyClass itself. If you know there will never be any subclasses, you might as well use @staticmethod. Commented Feb 7, 2023 at 22:44
  • just a question, what is the usecase of creating class instance in same class via two methods? Commented Feb 7, 2023 at 22:53
  • 1
    @sahasrara62 it was just an illustrative example Commented Feb 7, 2023 at 22:55

1 Answer 1

5

Two big advantages of the @classmethod approach:

First, you don't hard-code the name. Given modern refactoring tools in IDEs, this isn't as big of a deal, but it is nice to not have your code break if you change the name of your Foo, class to Bar::

class Bar:
    @statmicmethod
    def make_me():
        return Foo()

Another advantage (at least, you should understand the difference!) is how this behaves with inheritance:

class Foo:

    @classmethod
    def make_me_cm(cls):
        return cls()

    @staticmethod
    def make_me_sm():
        return Foo()

class Bar(Foo):
    pass

print(Bar.make_me_cm()) # it's a Bar instance
print(Bar.make_me_sm()) # it's a Foo instance
Sign up to request clarification or add additional context in comments.

1 Comment

thanks for the response. I'm trying to work out what's exactly the advantage in your second argument. Is it that the inheritance behaves "as expected", i.e. creating and instance of Bar instead of Foo?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.