Frage

Is naming a regular method init only confusing or is it an error?

class A:
    def __init__(self, x):
        self.x = x

    def init(self, y):
        self.y = y**2

    def reset(self):
        self.y = 0

I have encountered such a construction during review. Should I mark is as an issue?

War es hilfreich?

Lösung

I'd suggest using setup instead of init to remove any ambiguity for the reader. While syntactically correct, unreadable/ambiguous code results in harder-to-maintain products.

Also, if such methods exist in a class (init, reset, setup...), I always try to use them in the constructor itself as they're usually meant to leave the object in a known state. For instance:

def __init__(self, x):
  self.reset()
  self.x = x

This helps reduce the code duplication and simplify the possible states an object can be in.

Andere Tipps

Should I mark is as an issue?

That really depends on the coding standard you are using.

Is it confusing? Yes, to the human. Especially in verbal conversations, having to clarify whether you mean __init__ vs init will waste people's time.

If you want to argue against this practice, use your coding standards' naming guidelines. Many coding standard species that names should be clear and unambiguous, and names like this are ambiguous to the human.

Is it an error? No. The python parser and interpreter won't error out, as it is unambiguous to it. To the python compiler/interpreter, those are unambiguous and there's a totally clear difference between __init__ and init.

One problem with this class is that reset doesn't result in an A that "has just been constructed", which will probably surprise people.

If it were either

class A:
    def __init__(self, x):
        self.x = x

    def init(self, y):
        self.y = y**2

    def reset(self):
        del(self.y)

or (more preferably)

class A:
    def __init__(self, x):
        self.x = x
        self.y = 0

    def init(self, y):
        self.y = y**2

    def reset(self):
        self.y = 0

then it would be less bad.

That being said, I dislike any class that has a setup, gather members, init or whatever named method, which users must call before the real purpose of the class can be used. If you really need two phase initialisation, return a factory object from the first call, and only instantiate on the second

class A:
    def __init__(self, x, y):
        self.x = x
        self.y = y**2
    # members can assume y exists

def defferedA(x):
    def inner(y):
        return A(x, y)
    return inner

That makes no sense.

What is something called init supposed to do besides initializing an object with an initial state, which is, what a constructor does, which in turn is, what __init__ should do in this case?

In the context given, init_y whould make (more) sense.

Perhaps classmethods help you in this context - but hence your example is contrieved, I do not know.

Lizenziert unter: CC-BY-SA mit Zuschreibung
scroll top