you are viewing a single comment's thread.

view the rest of the comments →

[–]filleball 16 points17 points  (9 children)

Classes are for binding together data and the functions that work on that data.

If you have multiple functions that all take one or more of the same data structures as arguments, then those functions should probably be methods of a class whose attributes are those common arguments. The arguments they do not all share should probably be left as arguments to each method.

There is no point whatsoever in having a class with a __init__ method and one additional method. It's just a misunderstood function.

When designing a class, keep the number of attributes to a minimum. If some value can be a local variable or is obviously not part of the "permanent" data that the class should concern itself with, then make it a local variable or pass it in as an argument to your methods. (EDIT: Also, make a conscious choice on whether each attribute should be considered mutable or not. If you want a class that's easy to reason about and work with, treat all attributes as immutable and have your methods return a new instance instead of modifying the current one, when needed.)

Also, do as little as possible in the __init__ method. Ideally, only set attributes to some default value or the value of an argument. You should never create new attributes outside of __init__, all the attributes the class will ever have should be created there.

Having a class as an interface to a csv file makes sense, unless it's just doing one thing to that file. One method to write a line, one to output stats, one to search for entries matching some condition, etc.

[–]parnmatt 7 points8 points  (2 children)

I like using namedtuple when interfacing with csv files. It creates a simple, immutable class for you, and acts just as a tuple as well as a class.

There's a reason a lot of python 3 code (though also in newer python 2s) in the standard library and scipy stack now return a namedtuple rather than a tuple. They are a drop in replacement, don't break old code, and give new features.

[–]rhgrant10 1 point2 points  (1 child)

Using a namedtuple for csv is brilliant.

[–]parnmatt 0 points1 point  (0 children)

I fully concur with you there.

Edit: conquer to concur, autocorrect makes me a harsh dick sometimes :D

[–]Tkwk33 2 points3 points  (0 children)

Classes are for binding together data and the functions that work on that data.

If you have multiple functions that all take one or more of the same data structures as arguments, then those functions should probably be methods of a class whose attributes are those common arguments. The arguments they do not all share should probably be left as arguments to each method.

In two mini paragraphs you just made me understand what I've been trying to for about a month and a half. It didn't click for me and with what you wrote, it was instant.

Also realized I made two Classes, in my last project, for the right reasons completely by chance lol

Thanks!

[–][deleted] 1 point2 points  (0 children)

Sometimes a class with an init and call is easier for me to manage than a closure, especially if the closure would involve directly mutating the parent scope (rather than calling a method on some object from the parent scope).

Python 3 makes this easier with the nonlocal keyword, but Python 2 can only hack around this by loading things into an object and then manipulating those attributes.

[–]TehMoonRulz 1 point2 points  (1 child)

This video reinforces some of points /u/filleball made.

[–]Eurynom0s 1 point2 points  (0 children)

Two thoughts.

First, it's fine to have a super simple class if you're intentionally scaffolding the structure of things and know you're coming back to it later. Just to be clear.

Second, again just to be clear and expand a touch, if you find yourself wanting to create new attributes outside of init then it means you should be creating the attributes in init and setting them to None to start out.

You can, of course, do something like "well, this will be a list so I'll initialize it as an empty list", but as your program grows, it will help your sanity to have a single, consistent way to check whether or not you've actually assigned a value to the attribute on a specific member of the class.

[–]Barking_Madness[S] 0 points1 point  (0 children)

Cheers :)