0

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?

  • 1
    There are certainly more pressing issues in this sample than the misleading method name. Why is x mandatory and y optional? Why is the square of y stored rather than y? – Kilian Foth Apr 23 '18 at 12:09
  • 2
    @KilianFoth Come on, those are just examples. Those methods do obviously other things, but I can't paste here production code :) – hans Apr 23 '18 at 12:22
2

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.

| improve this answer | |
3

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.

| improve this answer | |
2

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
| improve this answer | |
  • This does not address my question at all and proposes rather over-elaborate solution. – hans Apr 23 '18 at 13:00
  • 1
    @hans "Is an init method a problem?" Yes, but not because it has a name similar to __init__ – Caleth Apr 23 '18 at 13:16
1

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.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.