[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Style Q: Instance variables defined outside of __init__

> On Mar 19, 2018, at 10:27 AM, Ned Batchelder <ned at nedbatchelder.com> wrote:
> On 3/19/18 1:04 PM, Irv Kalb wrote:
>> I am building some classes for use in future curriculum.  I am using PyCharm for my development.  On the right hand edge of the PyCharm editor window, you get some little bars indicating warnings or errors in your code.  I like this feature and try to clean up as many of those as I can.  However, there is one warning that I am seeing often, and I'm not sure about how to handle it.  The warning I see is:
>> "Instance attribute <instance variable name> defined outside of __init__ ..."
>> <snippage>
> I understand this tension: it's nice to assign only meaningful values, and to do it in as few places as possible.  But it's also nice to have all of your attributes in one place.  This is a by-product of Python having no declarations, only definitions (assignments).  So to mention the attributes initially, you have to choose a value for them.  If I were to add faceUp to __init__, I would assign False to it.

Thanks to everyone who responded to my question - good discussion.  Special thanks to Ned who accurately described the "tension" that I am trying to resolve.

I am aware of all the issues involved.  My example code was an attempt to demonstrate the clearest, simplest case possible.  My question is not about this small case.  In classes designed for full games, I often have a "reset" method that resets many instance variables (and potentially other display fields and graphics) for a new round of playing a game.  Grouping this into a method called something like "reset" makes logical sense to me.  You tell the game object to reset itself, and it does whatever it needs to do to reset for a new round.  My __init__ method calls reset to initialize the first round of the game.  This ensures that every play of the game goes through the same initialization.

With the approach suggested (initializing instance variables in my __init__ and in method like reset), I would wind up duplicating all such code.  I know myself, and I am worried that this has the potential for introducing an error in my coding (specifically, add an initialization of an instance variable in my __init__ but then forget to add the same line in my "reset" method).  So the tension that I am feeling is in the trade off of the "Don't Repeat Yourself" (DRY) rule vs the nicety of defining all instance variables in the __init__ method, and with that a resolution to the lint warnings.  

After further thought (and considering by the discussion here), I think that the DRY rule outweighs the other.  I will keep my separate initialization methods, and call them at the end of my __init__ methods.

Again, the real reason I'm asking for the "best practices" (even though I hate that term), is because I want to explain this concept to students who will be learning the basics of OOP.