[Tutor] Python scripts: to use class or not — what is the best practice?

DL Neil PyTutor at DancesWithMice.info
Mon Mar 16 18:41:58 EDT 2020


On 16/03/20 3:07 PM, Igwe Kalu wrote:
> Hi Community,
> 
> I need your feedback on a possibly simple idea.
> 
> Python scripts: to use class or not — what is the best practice?<https://softwareengineering.stackexchange.com/questions/406585/python-scripts-to-use-class-or-not-what-is-the-best-practice>
> 
> The details of my question are posted on https://softwareengineering.stackexchange.com/questions/406585/python-scripts-to-use-class-or-not-what-is-the-best-practice
> 
> I would greatly appreciate your inputs there, thank you.


+1 to previous responses. Valuable learning opportunities!


I may use class(es) more than others, and may be more data-centric. 
There are arguments both-ways, as you've read.


When designing a program, I look for 'entities' - the who and the what, 
relating to the objectives. I also appreciate, and (some may say) 'over 
practice' the concept of 'information hiding'.


After basic design (likely on a white-board), I start 'coding' by 
encoding application-objectives/requirements into comments. Logically 
then, once entities are realised, such decisions can be 'documented' 
with a class statement and docstring (and pass)!

Similarly, delving into greater detail, data attributes can be added, 
with type information (if practiced) and explanatory comments, as 
appropriate. Also functional attributes (methods and functions) can be 
denoted with a def, docstring, and pass. (not forgetting the 
import-ation of libraries and other third-party or utilities! etc)

Where possible, the bulk of the code's structure is thus transferred 
from the 'design documents' into source-code.

Somewhere around this point (depends upon the application, if multiple 
coders are involved, etc, etc), I will probably switch from 'top-down 
design' to 'bottom-up', by following Test-Driven Development practice.

It must be acknowledged that one's method and how practical the above 
may appear, is a function of experience (and comfort with the approach). 
YMMV big time!


Back in the ?good, old days, "subroutine libraries" came into being, and 
for much the same advantages, we became convinced of "modular 
programming". (those older "modular" code-units might be translated into 
modern 'Python' as "namespaces" - and thus include modules, classes, 
methods (inside classes), and functions (outside classes)).

More recently Grady Booch's view of Object-Oriented Programming (OOP) 
talked of "encapsulation" - I'm a little wary of quoting his ideas 
(which are nevertheless valid) because their implementation is an 
anathema to Python and the pythonic way of thinking, eg we don't 
(really) have "private" attributes nor do we need 'getters' or 'setters' 
in the normal case...

In both cases, the idea is that calling a 'routine' reduces "cognitive 
load". (and should "document" one's code!) Attempting to build from the 
example given, "start" would become THE routine, eg

	def optimise_simulation():
		etc

Thus, someone reading the 'mainline' code has been given enough 
knowledge to be able to decide to keep reading and see how the rest of 
the application fits-together. Alternately, the reader wanting to 'dive' 
into the optimisation itself, can find the function and commence reading 
the detail - which would lead to the branch-decision and the two 
alternative 'actual' implementations...


Back to the meat of the question: if the 'simulation' were already a 
class, likely these routines would be implemented as methods.

If however the code might be applicable to another class, or indeed to 
code which is not part of a class (ie the 'subroutine library' idea or 
in the modern parlance: "reuse"), then it would be inappropriate to 
'bury it' within a class that cannot also be part of such re-use.

Just to offer you a (sort of) third option, in such a 
'shared'/multiple-use situation, you could consider coding such utility 
routines as a "mixin [class]" which is either inherited or included into 
(multiple units of) host code by "composition".

Alternately, it may be appropriate to view the optimisation process as a 
full-fat, separate, class (in such vague terms, I don't interpret a 
process as an "entity" - but others may disagree...)


Is there a right/wrong answer? Doubt it! During code reviews, in such a 
situation, people often comment "I would [not] have used a class 
'here'." However, such usually passes as a comment (perhaps a 
learning-opportunity), and seldom leads into a criticism (by itself) 
which requires a re-write/re-factoring.
(in my experience)


There's a difference between someone who has eleven years of 
experiences, and someone who repeats one year of experience eleven times!

My suggestion, if I may (and bearing in-mind what others have already 
said about choosing one way over the other according to certain 
circumstances): try coding (as you have) the function-way 'today', but 
next time you're faced with something similar, employ classes. Later, 
reflection on (learning from) those experiences will (intelligently) 
equip you for 'the future'...
-- 
Regards =dn


More information about the Tutor mailing list