3

How can I get a reference to the class in a static method?

I have following code:

class A:
    def __init__(self, *args):
        ...
    @staticmethod
    def load_from_file(file):
        args = load_args_from_file(file)
        return A(*args)
class B(A):
    ...

b = B.load_from_file("file.txt")

But I want to B.load_from_file return object of type B, not A. I know if load_from_file wouldn't be a static method I could do

def load_from_file(self, file):
        args = load_args_from_file(file)
        return type(self)__init__(*args)
5
  • 4
    A staticmethod has no access to the class by definition. Why don't you want something else, say a classmethod? Commented Aug 18, 2020 at 12:24
  • Yes, thanks, Never heard about class method and it is exactly I need. Commented Aug 18, 2020 at 12:34
  • @JaraM I suggest searching also for factory method pattern (more general term) especially if you want to compare with languages other than python. Commented Aug 18, 2020 at 12:38
  • 1
    @Daweo: To be clear, that design pattern is designed to cover gaps in other languages; in Python, stick to classmethods. Commented Aug 18, 2020 at 12:47
  • @Daweo still good to know something like that exists :) Commented Aug 18, 2020 at 12:49

1 Answer 1

6

This is what classmethods are for; they're like staticmethod in that they don't rely on instance info, but they do provide info about the class it was invoked on by providing it implicitly as the first argument. Just change your alternate constructor to:

@classmethod                          # class, not static method
def load_from_file(cls, file):        # Receives reference to class it was invoked on
    args = load_args_from_file(file)
    return cls(*args)                 # Use reference to class to construct the result

When B.load_from_file is invoked, cls will be B, even though the method is defined on A, ensuring you construct the correct class.

In general, any time you find yourself writing alternate constructors like this, you always want a classmethod to enable inheritance properly.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.