Re: [Tutor] When to use classes

2017-08-19 Thread Steven D'Aprano
On Sat, Aug 19, 2017 at 11:34:10AM -0600, Mats Wichmann wrote:

> It makes some sense though; computational code just goes ahead and
> computes.  In the graphical UI world, interesting things happen when an
> event you can't exactly plan for takes place.  From the point of view of
> a computer program, waiting for somebody to move a mouse and click it is
> a slow, infrequent, and unpredictable event, so you set up callbacks
> which are invoked when one of those events happens, and in the meantime
> you can either do other productive work, or do nothing at all (let other
> programs on the computer do work).  I'm finding it hard to imagine
> tkinter without them...

I've never got into GUI programming because I was so thoroughly spoiled 
by one of the first programming languages that I learned that everything 
since then feels like going back to the Dark Ages. Having to care about 
low-level details like creating buttons, installing callbacks and so 
forth just feels wrong.

There is an alternative to callback based GUI frameworks, and that is an 
message-passing, event-driven language. The framework handles the events 
for you, and fires off messages to objects. If the object doesn't handle 
the event, it is sent to the next object in the message-passing 
heirarchy.

The language was Hypertalk, the scripting language of Apple's Hypercard 
application in the mid to late eighties.

Hypercard was seen by Apple as a kind of Rolodex application, with a 
"card" metaphor, and programmable objects (text fields and buttons) that 
you can copy and paste between files. Apple invisiged that developers 
would program the objects and users would simply copy and paste them, 
and to their utter surprise they were overwhelmed by the number of end 
users who started programming their own objects.

By today's standards it is woefully primitive: only a single window, of 
a fixed size, black and white graphics, and only a fixed set of 
pre-defined GUI widgets and no way to create your own. But it is 
remarkable just how much power there is in just two widgets, text fields 
and buttons, especially since the buttons can be specialised into push 
buttons, radio buttons and checkbox buttons.

But I digress... the Hypercard model was that of a stack of cards. Each 
stack (Hypercard document) consisted of at least one shared background 
used by at least one card. Cards inherited their look, state and 
behaviour from their background, but could override any part of that.

You used the integrated GUI designer to lay out your shared objects in 
the background, and customised objects on the card.

The Hypercard application managed the GUI event loop for you. It tracked 
the mouse and the keyboard, and other events, and each time it noticed 
an event, it sent a message to the appropriate object (a widget, card, 
background or stack). That object could either handle the message, or 
ignore it. If it ignored the message, it passed on to the next object in 
the heirachy.

To program your "stack", you create message handlers that respond to 
events. E.g.:

on mouseUp
  # sent when the mouse button is released over the object

on idle
  # sent when nothing else is happening

on opencard
  # sent when we've just navigated to another card

on closecard
  # sent when we've just navigated away from the current card


If this looks a tiny bit like Javascript, that's because Javascript 
borrowed the idea and language of handlers from Hypertalk and 
Hypercard.

To call a handler in another object, you sent your own message, and the 
Hypercard application would manage the details:

send "print" to field "Address" of card "George"

That message would be sent via the same message path as any other event, 
so if the field itself couldn't handle it, it would next go to the card 
"George", then the card's background, then the current stack, and 
finally Hypercard itself, which would complain that it didn't know 
anything about "print" events. (Events it did know about, like idle or 
mouseDown or closeCard, would just be silently ignored.)


-- 
Steve
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] When to use classes

2017-08-19 Thread Steven D'Aprano
On Sat, Aug 19, 2017 at 11:00:51AM -0500, boB Stepp wrote:

> I try to keep this in mind.  Another thing I'm currently struggling
> with is when to use inheritance vs. separate, independent classes.

Raymond Hettinger has a good video presentation about the use of classes 
and inheritance for delegating work. (That is not to be confused with 
delegation as an alternative to inheritance.)

I think this is the video, but I don't have time to check:

The Art of Subclassing

http://www.youtube.com/watch?v=miGolgp9xq8

If its the one which starts off with him talking about his newly born 
child, it is the one.

And if not, it is probably worth watching anyway, because Raymond's 
talks are always excellent value.

The traditional viewpoint of inheritance is that it is used for 
specialisation, where each subclass is a kind of the parent class:

class Animal:
# all generic code for animals goes here

class Mammal(Animal):
# mammals are a kind of animal
# specialise the animal code for mammals

class Dog(Mammal):
# dogs are a kind of mammal
# specialise the mammal code for dogs

class Collie(Dog):
# collies are a kind of dog
# specialise the dog code for the collie breed

lassie = Collie()

If you ever hear people talking about the Liskov Substitution Principle, 
that's the model they have in mind. But it's not the only one possible.

Raymond talks about inheritance as expressing a parent-child 
relationship, where the child can delegate tasks to the parent, but the 
child doesn't necessarily need to be seen as "a kind of" whatever the 
parent is.

That's the model used by mixin classes (or traits, a variation on 
mixins).


-- 
Steve
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] When to use classes

2017-08-19 Thread Steven D'Aprano
On Sat, Aug 19, 2017 at 10:52:45AM -0500, boB Stepp wrote:

> This thought had occurred to me.  Sometimes I wish there was a
> mechanism in Python to create a binding to data where both were
> unchangeable/immutable.  Yes, I could use an immutable data type, but
> if I bind an identifier to it that I want to *only* identify that
> data, AFAIK it will always be possible for that identifier to be
> rebound to a different object.

A "constant", in the sense that once bound, it cannot be unbound or 
re-bound to another object.

There are some tricky hacks you can use to get something almost like a 
constant, e.g.

https://code.activestate.com/recipes/65207-constants-in-python/

but without language support they're probably not worth bothering with.


-- 
Steve
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] When to use classes

2017-08-19 Thread Cameron Simpson

On 19Aug2017 11:00, boB Stepp  wrote:

On Sat, Aug 19, 2017 at 4:04 AM, Peter Otten <__pete...@web.de> wrote:

[...]

The lesson is that Python already provides some powerful ready-to-use
classes that take you a long way without having to write your own custom
classes.


In my beginning experiments to date writing classes, I have often
while writing my toy examples realized, "Why am I writing a class?
Python already does this more straightforwardly with ."  Of course not knowing all of Python I sometimes
don't realize this until well after I wrote the unneeded class.


Personally, I do this a lot. It does cost some time, but it also has 
advantages. You get to explore the problem space from the point of view of your 
own needs, and you get insight into the costs/benefits of various ways of doing 
things.


Then you can come back to the presupplied library do various things: understand 
why its interfaces may be designed the way they were, refactor your code (the 
larger problem) on top of the presupplied library, and sometimes decide that 
the presupplied library doesn't meet your needs (or meets them poorly), and 
then you have this useful additional library of your own.


The flipside is to do a little research and start with the presupplied library 
and take that as far as it will go, then build on that. Particularly when the 
library solves some problem you find boring. Also, the presupplied library 
often covers corner cases you may miss - it has (probablym hopefully) been well 
debugged - writing your own has that cost.


You get less insight into internals, but you also get off the ground faster.


Another alternative to (explicit) classes are generators which are an
elegant way to hold state and provide a simple interface.

[...]

I hope I don't forget this point between now and when I get the
database part of my project going!


One thing that I think can be important is to code the upper layers in the 
terms of your larger problem, not in terms of the lower level library's 
interface. In between the two will be functions or methods of your own whose 
interfaces are your own operation, and which call the library to accomplish the 
task, providing some separation between a natural expression of your upper 
level problem and what you might write if you were building from the bottom and 
thinking in the library's terms.


Cheers,
Cameron Simpson  (formerly c...@zip.com.au)

Ride to not crash. Dress to crash. Live to ride to not crash again.
- Lawrence Smith, DoD#i, lawre...@msc.cornell.edu
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] help with subprocess module

2017-08-19 Thread Cameron Simpson

On 19Aug2017 06:13, kay Cee  wrote:

   update_log = open('update_log.txt', 'r+')


Normally one would use 'a' (append) for a log open. I don't see what 'r+' 
accomplishes for you. In particular I expect it would always write at the start 
of the log file, overwriting whatever was there. Which might be your problem.


Others have made other remarks.

I'm not sure any of your problems have to do with the subprocess module itself.

Cheers,
Cameron Simpson  (formerly c...@zip.com.au)
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] help with subprocess module

2017-08-19 Thread Alan Gauld via Tutor
On 19/08/17 11:13, kay Cee wrote:

> import subprocess
> import time
> import datetime
> 
> class UpdateError(Exception):
> pass

In defining your own type of Exception you implicitly
say that you will be raising it somewhere. But you
never raise this exception in your code...

> def update():
> while True:
> try:
> update_log = open('update_log.txt', 'r+')
> time.sleep(1)

Do you really want to run apt-get update every second?
That seems way too frequent, every hour would be a lot,
every day more reasonable.

> subprocess.call(['apt-get', 'update', '-y'])
> date = datetime.datetime.now()
> update_log.write("System was updated sucessfully on {}\n".format
> (str(date)))
> subprocess.call(['reboot'])

And do you want your computer rebooting after every
successful apt-get update? You really should not have
to do that. Especially every second, you are likely
to make your system unusable.

> except UpdateError:
> print("Update Error!!!")

Since nothing raises an UpdateError you will never receive one.
You are more likely to get an OSError or an IOError or a
FileNotFound or similar.

> update_log.close()

Since you open the file inside the loop you should close
it inside the loop. Ideally inside a finally clause.
Or better still use a with... construct to open the
file then you don;t need to close it yourself.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] help with subprocess module

2017-08-19 Thread Mats Wichmann
On 08/19/2017 04:13 AM, kay Cee wrote:
> I made a python script that will update a Ubuntu Server every second and
> writes asuccess message  and date to a log file, but for some reason the
> file is not being written to.
> 
> Here is the Script:
> 
> #!/usr/bin/python3
> 
> import subprocess
> import time
> import datetime
> 
> class UpdateError(Exception):
> pass
> 
> def update():
> while True:
> try:
> update_log = open('update_log.txt', 'r+')
> time.sleep(1)
> subprocess.call(['apt-get', 'update', '-y'])
> date = datetime.datetime.now()
> update_log.write("System was updated sucessfully on {}\n".format
> (str(date)))
> subprocess.call(['reboot'])
> except UpdateError:
> print("Update Error!!!")
> update_log.close()
> 
> if __name__ == '__main__':
> update()

Hate to not just "answer the question", but what are you trying to
accomplish with this script?

You certainly don't want to call "apt-get update -y" in loop this fast.
Why are you then rebooting? (update doesn't change the system, only the
apt cache info)

Ubuntu has a way to do this stuff as a background task anyway.

For logging, you may want to actually use Python logging facilities.


All those said, the way you want to debug something like this is to run
a much more benign task through subprocess, before moving on to big (and
slow) tasks.

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] When to use classes

2017-08-19 Thread Alan Gauld via Tutor
On 19/08/17 17:00, boB Stepp wrote:

> I try to keep this in mind.  Another thing I'm currently struggling
> with is when to use inheritance vs. separate, independent classes.

The golden rule is if the child is not a kind-of the parent then
it should be delegation not inheritance. Never use inheritance as
a mechanism for construction, its for specializing types.

Another anti-pattern to look out for is if you are adding a lot
of new methods rather than overriding inherited methods there's
a good chance you are going the wrong way.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] help with subprocess module

2017-08-19 Thread Peter Otten
kay Cee wrote:

> I made a python script that will update a Ubuntu Server every second and
> writes asuccess message  and date to a log file, but for some reason the
> file is not being written to.
> 
> Here is the Script:
> 
> 
> #!/usr/bin/python3
> 
> 
> 
> import subprocess
> 
> import time
> 
> import datetime
> 
> 
> class UpdateError(Exception):
> 
> pass
> 
> 
> def update():
> 
> while True:
> 
> try:
> 
> update_log = open('update_log.txt', 'r+')
> 
> time.sleep(1)
> 
> subprocess.call(['apt-get', 'update', '-y'])
> 
> date = datetime.datetime.now()
> 
> update_log.write("System was updated sucessfully on
> {}\n".format
> (str(date)))
> 
> subprocess.call(['reboot'])

Hm, are you sure you want to reboot here?

> 
> 
> except UpdateError:
> 
> print("Update Error!!!")
> 
> 
> update_log.close()
> 
> 
> if __name__ == '__main__':
> 
> update()
> ___
> Tutor maillist  -  Tutor@python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] When to use classes

2017-08-19 Thread Alan Gauld via Tutor
On 19/08/17 10:04, Peter Otten wrote:

> nicer interface. Nobody would want to write
> 
> a + b * c
> 
> as
> 
> add(a, mul(b, c))

Unless they program in Lisp perhaps :-)


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


[Tutor] help with subprocess module

2017-08-19 Thread kay Cee
I made a python script that will update a Ubuntu Server every second and
writes asuccess message  and date to a log file, but for some reason the
file is not being written to.

Here is the Script:


#!/usr/bin/python3



import subprocess

import time

import datetime


class UpdateError(Exception):

pass


def update():

while True:

try:

update_log = open('update_log.txt', 'r+')

time.sleep(1)

subprocess.call(['apt-get', 'update', '-y'])

date = datetime.datetime.now()

update_log.write("System was updated sucessfully on {}\n".format
(str(date)))

subprocess.call(['reboot'])


except UpdateError:

print("Update Error!!!")


update_log.close()


if __name__ == '__main__':

update()
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] When to use classes

2017-08-19 Thread Mats Wichmann
On 08/19/2017 10:00 AM, boB Stepp wrote:

>> (That was easy; but I wonder what tkinter would look like without
>> callbacks...)
> 
> I wish I knew more so that I could fully wonder about this myself.
> You might even be making a clever joke and I am clueless.

All graphics frameworks depend heavily on callbacks, to the point where
I'm starting to recognize that callback laden code in other contexts was
probably written by a (former?) graphics programmer :)

It makes some sense though; computational code just goes ahead and
computes.  In the graphical UI world, interesting things happen when an
event you can't exactly plan for takes place.  From the point of view of
a computer program, waiting for somebody to move a mouse and click it is
a slow, infrequent, and unpredictable event, so you set up callbacks
which are invoked when one of those events happens, and in the meantime
you can either do other productive work, or do nothing at all (let other
programs on the computer do work).  I'm finding it hard to imagine
tkinter without them...

>>> - if you can't, encapsulate it in classes.
>>
>> I think it's important that you say "classes", not "class". As with
>> functions three small dedicated classes are much better than one big know-
>> it-all/do-it-all class.
> 
> I try to keep this in mind.  Another thing I'm currently struggling
> with is when to use inheritance vs. separate, independent classes.

or when to use a class that contains an instance of another class...

It ought to feel natural... there's a lot in common, but we want to do a
little bit of specialization, that's a decent case for inheritance. So
they claim.  Except the examples are always so simplistic in the
literature: write a class called Human, then specialize it into Man and
Woman to deal with gender differences.  Sure.  And as recent political
kerfuffles have highlighted, what about an instance that is not clearly
one or the other?  What about all those pesky little details that are
not as simple as "has two arms" that are never part of the "real world"
models, but are very much part of the programming environment when you
go to implement something?

Inheritance describes a relationship - "is a".  a Volvo is-a Car. A
Checking Account is-a Bank Account. If you can't make that feel natural,
then it's probably not the right model.

(my opinions only)


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] When to use classes

2017-08-19 Thread boB Stepp
On Sat, Aug 19, 2017 at 4:04 AM, Peter Otten <__pete...@web.de> wrote:
> Steven D'Aprano wrote:
>
>> Mostly for Bob, but also for anyone else interested:
>>
>> When To Use Classes
>>
>> http://kentsjohnson.com/stories/00014.html
>
> Just a minor nit, but you don't even need a custom function for the callback
>
> result = []
> db.query(sql, result.append)
>
> The lesson is that Python already provides some powerful ready-to-use
> classes that take you a long way without having to write your own custom
> classes.

In my beginning experiments to date writing classes, I have often
while writing my toy examples realized, "Why am I writing a class?
Python already does this more straightforwardly with ."  Of course not knowing all of Python I sometimes
don't realize this until well after I wrote the unneeded class.

> Another alternative to (explicit) classes are generators which are an
> elegant way to hold state and provide a simple interface.
>
> In modern Python db.query() should be an iterable to that the above can be
> written
>
> result = list(db.query(sql))

I hope I don't forget this point between now and when I get the
database part of my project going!

> (That was easy; but I wonder what tkinter would look like without
> callbacks...)

I wish I knew more so that I could fully wonder about this myself.
You might even be making a clever joke and I am clueless.


>> - if you can't, encapsulate it in classes.
>
> I think it's important that you say "classes", not "class". As with
> functions three small dedicated classes are much better than one big know-
> it-all/do-it-all class.

I try to keep this in mind.  Another thing I'm currently struggling
with is when to use inheritance vs. separate, independent classes.


-- 
boB
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] When to use classes

2017-08-19 Thread boB Stepp
On Sat, Aug 19, 2017 at 3:07 AM, Alan Gauld via Tutor  wrote:
> On 19/08/17 08:52, Alan Gauld via Tutor wrote:
>
> Following up my own post - a sure sign of failure to communicate :-(
>
>> On 19/08/17 05:26, boB Stepp wrote:
>>
>>> related methods needs to share the same values and a class would tidy
>>> this up nicely without the need for any globals
>
>> Indeed, but its important to remember that class attributes
>> are in effect just global data confined to a smaller context,
>> and they share many of the same issues of global data.

This thought had occurred to me.  Sometimes I wish there was a
mechanism in Python to create a binding to data where both were
unchangeable/immutable.  Yes, I could use an immutable data type, but
if I bind an identifier to it that I want to *only* identify that
data, AFAIK it will always be possible for that identifier to be
rebound to a different object.

>> Classes don't remove the problems with globals, they just
>> limit the damage.
>
> I should have added that making the globals into instance
> variables rather than class attributes improves the
> situation still further since it effectively enables
> multiple "threads" of execution of your function sequence.
>
> The big issue I was alluding to is the solution whereby a
> sequence of functions sharing data is translated into
> a Class with class level variables and a bunch of
> static/class methods. (This is often seen in bad
> Java code). Shared instance data is much less likely
> to be changed in bad ways although still a form of global
> (within the instance).

I think the author was also emphasizing your points, but in a
different way.  He said:


Maybe you decided to put your shared state into global variables
instead of creating a class. The single client of your module works
great. But what if you have a second client that needs its own copy of
the module state, or you need to use the module from multiple threads?
You are getting wacky results as the module trips over itself trying
to serve two masters. How can you have two copies of the global state?
Move it into a class! Each client has its own instance of the class
with its own state.


> But creating classes just to avoid globalizing data
> should be a last resort solution. Classes should
> serve a conceptual function too in helping to understand
> the role of the functions within the overall system.
> And that, coincidentally, will usually result in the
> functions that share data being grouped in the
> same class.

I did say in my original post "...related methods...", but take the
importance of your point!



-- 
boB
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] When to use classes

2017-08-19 Thread Peter Otten
Steven D'Aprano wrote:

> Mostly for Bob, but also for anyone else interested:
> 
> When To Use Classes
> 
> http://kentsjohnson.com/stories/00014.html

Just a minor nit, but you don't even need a custom function for the callback

result = []
db.query(sql, result.append)

The lesson is that Python already provides some powerful ready-to-use 
classes that take you a long way without having to write your own custom 
classes.

Another alternative to (explicit) classes are generators which are an 
elegant way to hold state and provide a simple interface. 

In modern Python db.query() should be an iterable to that the above can be 
written

result = list(db.query(sql))

(That was easy; but I wonder what tkinter would look like without 
callbacks...)

> He says:
> 
> You may have several functions that use the same state
> variables, either reading or writing them. You are passing
> a lot of parameters around. You have nested functions that
> have to forward their parameters to the functions they use.
> You are tempted to make some module variables to hold the
> state.
> 
> You could make a class instead!
> 
> 
> 
> Indeed you could, and sometimes you should, but we can see a problem
> here. The situation described is a bad situation to be in: there is too
> much coupling between functions, too much state being passed around.
> 
> Ideally we should try to *reduce the coupling* between components, if
> possible, and hence make the program less complex. OO design tries to
> encapsulate the coupling within (hopefully) a single class, but it does
> nothing to reduce the coupling or complexity.
> 
> So I would say:
> 
> - if your code is complex, with lots of connections between
>   components (coupling), try to reduce the coupling and make
>   the code simper;

Even if you can simplify the code with functions classes often give you a 
nicer interface. Nobody would want to write

a + b * c

as

add(a, mul(b, c))


> - if you can't, encapsulate it in classes.

I think it's important that you say "classes", not "class". As with 
functions three small dedicated classes are much better than one big know-
it-all/do-it-all class.

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] When to use classes

2017-08-19 Thread Alan Gauld via Tutor
On 19/08/17 08:52, Alan Gauld via Tutor wrote:

Following up my own post - a sure sign of failure to communicate :-(

> On 19/08/17 05:26, boB Stepp wrote:
> 
>> related methods needs to share the same values and a class would tidy
>> this up nicely without the need for any globals 

> Indeed, but its important to remember that class attributes
> are in effect just global data confined to a smaller context,
> and they share many of the same issues of global data.

> Classes don't remove the problems with globals, they just
> limit the damage.

I should have added that making the globals into instance
variables rather than class attributes improves the
situation still further since it effectively enables
multiple "threads" of execution of your function sequence.

The big issue I was alluding to is the solution whereby a
sequence of functions sharing data is translated into
a Class with class level variables and a bunch of
static/class methods. (This is often seen in bad
Java code). Shared instance data is much less likely
to be changed in bad ways although still a form of global
(within the instance).

But creating classes just to avoid globalizing data
should be a last resort solution. Classes should
serve a conceptual function too in helping to understand
the role of the functions within the overall system.
And that, coincidentally, will usually result in the
functions that share data being grouped in the
same class.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] When to use classes

2017-08-19 Thread Alan Gauld via Tutor
On 19/08/17 05:26, boB Stepp wrote:

> related methods needs to share the same values and a class would tidy
> this up nicely without the need for any globals or needless passing of
> the exact same values around as parameters/arguments.

Indeed, but its important to remember that class attributes
are in effect just global data confined to a smaller context,
and they share many of the same issues of global data.
Functions(methods) can (and usually do) change the data
as a side effect of being called, without it being obvious
that self.foo() is modifying say, self.bar and self.baz, internally.

The advantage of a class is that at least it constrains the
candidate culprits to other members of our class, but the underlying
problem of changes by side-effect remains, even if reduced.

Classes don't remove the problems with globals, they just
limit the damage.

>> possible, and hence make the program less complex. OO design tries to
>> encapsulate the coupling within (hopefully) a single class, but it does
>> nothing to reduce the coupling or complexity.

exactly so.

> I really enjoyed reading this brief article.  He explained things
> rather clearly.  

Kent was a long time member of this group for many years.
I think he left just about the same time Steve appeared.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor