Another newbie question

james.moughan at sunderland.ac.uk james.moughan at sunderland.ac.uk
Mon Dec 12 14:27:32 EST 2005


Mike Meyer wrote:
> aleax at mail.comcast.net (Alex Martelli) writes:
> > Mike Meyer <mwm at mired.org> wrote:
> >> > "In addition to the full set of methods which operate on the coordinate as
> >> > a whole, you can operate on the individual ordinates via instance.x and
> >> > instance.y which are floats."
> >> That's an API which makes changing the object more difficult. It may
> >> be the best API for the case at hand, but you should be aware of the
> >> downsides.
> > Since x and y are important abstractions of a "2-D coordinate", I
> > disagree that exposing them makes changing the object more difficult, as
> > long of course as I can, if and when needed, change them into properties
> > (or otherwise obtain similar effects -- before we had properties in
> > Python, __setattr__ was still quite usable in such cases, for example,
> > although properties are clearly simpler and more direct).
>
> Exposing them doesn't make making changes more difficult. Allowing
> them to be used to manipulate the object makes some changes more
> difficult. Properties makes the set of such changes smaller, but it
> doesn't make them vanish.
>
> Take our much-abused coordinate example, and assume you've exposed the
> x and y coordinates as attributes.
>
> Now we have a changing requirement - we want to get to make the polar
> coordinates available. To keep the API consistent, they should be
> another pair of attributes, r and theta. Thanks to Pythons nice
> properties, we can implement these with a pair of getters, and compute
> them on the fly.

But the API cannot be consistent.  :-)   If setting r is expensive
because it requires several trig calculations but setting x is cheap,
that's an inconsistency.  It would be a vital one for any application
where I'd be likely to use a point.  You certainly couldn't change the
internal representation of a point from cartesian to polar without
breaking my code.

Good example from the C++ strandard library; string only specifies the
'literal' interface.  The internal representation is left totally
undefined... and so you can only program to a specific implementation
of string.  (Which, of course, can and does change between different
versions of a compiler, let alone between compilers.)  The STL got
things right, by contrast.

Sometimes these issues don't matter much.  Other times they do.
Perhaps they matter more to me because if the Python version is not
sufficiently fast, then I have to recode the thing in C++. ;-)

Anyway, my point:  some types of things fundamentally cannot be cleanly
seperated into an implementation and an API.  Whether a point is 2D or
polar is one of these issues, IMO.

This is obviously not to diss the whole idea of encapsulation and
modularisation.  I've worked on horrible code and beautiful code, and I
know what a difference these things make.  However, you also cannot
program blindly by general rules.  The toughest code I've ever had to
modify would probably have passed quite a few OO-style guides; the
author was really trying to adhere to a 'philosophy', he just didn't
get it.

James M

>
> If x and y can't be manipulated individually, you're done. If they
> can, you have more work to do. If nothing else, you have to decide
> that you're going to provide an incomplete interface, in that users
> will be able to manipulate the object with some attributes but not
> others for no obvious good reason. To avoid that, you'll have to add
> code to run the coordinate transformations in reverse, which wouldn't
> otherwise be needed. Properties make this possible, which is a great
> thing.
>
>           <mike
> --
> Mike Meyer <mwm at mired.org>			http://www.mired.org/home/mwm/
> Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.




More information about the Python-list mailing list