Style Q: Instance variables defined outside of __init__

Steven D'Aprano steve+comp.lang.python at pearwood.info
Mon Mar 19 19:36:31 EDT 2018


On Mon, 19 Mar 2018 10:04:53 -0700, Irv Kalb wrote:

> Some people say
> that this type of thing is fine and these warnings should just be
> ignored.  While others say that all instance variables should be defined
> in the __init__ method.

Whenever anyone says "you should do this", the question to ask is, "what 
bad thing will happen if I don't?"

You are getting a warning that self.faceUp is not defined in __init__. 
That means that there must be something bad that will happen if you don't 
define faceUp in __init__. Any idea what?

If there is no such bad thing that will happen, then PyCharm is crying 
wolf: it is wasting your time with a warning for a non-problem.


> I like that idea (and have done so in other
> languages), but if I define this variable there, what value should I
> give it?  Do I redundantly set it to the proper starting value (in case
> False), 

Why is it redundant? Since you're going to call conceal() anyway, why not 
just set the value and not bother with conceal? Especially since conceal 
appears to do nothing but set the flag.

Maybe it is *conceal* which is redundant and needs to be removed. On the 
other hand, 

    instance.conceal()
    instance.reveal()

is much more descriptive than "faceUp = True".


> or do as others have suggested, set it to None (which seems a
> little odd for something that I will use as a Boolean).

Ah yes, the good old "rubbish advice from the internet" strike again.

Unless your faceUp is intended to represent a *three state flag* (say, 
face up, face down, and standing on its side...) then why distinguish 
between None and False? What possible benefit to this is it?

My guess is that they're thinking that setting it to None indicates that 
it is uninitialised. Except that None is a perfectly good falsey value, 
so unless you specifically and carefully change *all* your code that 
currently says:

    if self.faceUp: ... 

into:

    if self.faceUp is None: raise SomeError
    elif self.faceUp: ...

then it makes no difference at all. Just use False and be done with it.


> I have many more similar cases.  For example, in many small game
> programs, at the end of my __init__ method, I call a "reset" method in
> the same class which initializes a bunch of instance variables for
> playing a game.  When the game is over, if the user wants to play again,
> I call the same reset method.  Very clean, and works very well, but all
> the instance variables defined in that reset method gets the same
> warning messages.

Indeed. Linters and code checkers often waste your time warning you 
against things that aren't wrong.



-- 
Steve




More information about the Python-list mailing list