Python evangelists unite!
Gareth McCaughan
Gareth.McCaughan at pobox.com
Thu Nov 29 19:51:14 EST 2001
brucehapman at hotmail.com wrote:
> Okay, I was extolling the benefits of Python to a friend of mine. He
> took strong exception to Python's OO model. <here we go again...>
>
> ME: Python's great--you can add members to instances OR classes
> on-the-fly!
> FRIEND: Why would you want to do that?
> ME: Uh...
> FRIEND: Besides, that's awful Object Orientation. If I start adding
> attributes to an instance of a class, it ceases to be an instance of
> that class. If I create a bunch of instances of the same class, they
> should be the same; they should have the same members.
Twaddle. They should provide the same interface. What members
they have is completely irrelevant to that, unless those
members are part of the interface you specify. (It so happens
that in Python there isn't really an in-language mechanism for
saying what's part of the interface and what isn't, but that
doesn't mean your objects don't have interfaces.)
And, of course, there's no law that says Python's objects
are only to be used for "proper" elegant OO programming.
They have other uses. :-)
> ME: Yeah, but with dynamicism, I can add a new pane to a GUI
> while it's running. I just change an instance to include a new pane,
> and...
> FRIEND: That's pretty cool, but it's not a reason, in and of itself,
> to make a language so dynamic. There must be some advantage to being
> able to add attributes during runtime. What are they?
> ME: Uh...
> FRIEND: And another thing! What's with encapsulation? There's no
> private!?!?!?
Here's an entry from my personal quotes file. It's about
CLOS (the Common Lisp Object System), which in most respects
is a very different beast from Python's object system; but
they have a similar attitude to encapsulation.
... it's just that in C++ and the like, you don't trust _anybody_,
and in CLOS you basically trust everybody. the practical result is
that thieves and bums use C++ and nice people use CLOS.
-- Erik Naggum
Someone who can't write well-formed OO programs without a
mechanism like "private" has serious problems with their
ability to write comments, or their ability to write other
documentation, or their discipline, or something.
Besides, in C++ at least, you can say
#define private public
#include "my-class.h"
#undef private
Yow!
> ME: <Screaming and running for cover>
>
> So, I need some help. I've checked out c.l.p and some on-line
> articles, and I just can't find good practicle examples of a program
> that adds members to instances (or classes) at runtime. Anybody got
> any? I don't want to have to start avoiding my friend....
The main advantage isn't the ability to add members at runtime
as such. That's just a side-effect of the fact that you don't
need explicit declarations of what can go in a class. And
*that*'s good for three reasons.
- Less repetitetition. Don't you just hate having to write
the same thing twice in C and C++? Programming's bad enough
for the wrists without having to write a pile of redundant
code.
- Handy for exploratory programming, where you sit at an
interactive prompt and play with things. If you suddenly
realise that you can make something go 10 times faster
by cacheing a crucial piece of information inside your
objects, it's nice that you can just add it and have it
work. I suppose that *is* adding members at runtime,
actually, but I suspect it's not the sort you had in
mind.
- One handy Python idiom is using an empty class definition
to provide things like "structs" in C.
class Empty: pass
stuff = Empty()
stuff.largest_prime = 44
stuff.modulus = -1
# etc
Having said that being able to add members at runtime isn't quite
the point, let me sort-of-contradict that by describing something
slightly icky I do in a program I use at work.
I'm collecting data from a sensor, and I want to be able to do
various bits of processing on the data. But not every packet of
data needs all the processing done on it. And, once all the
processing is done, I then want to stash a large number of
data-packets into a pickle for later use by another program.
I don't want my pickles to be hundreds of megabytes long.
So, my class looks a little like this:
class Packet:
def __init__(self, data):
self._data = data
self._processed = 0
def ensure_processed(self):
self._squares = map(operator.mul, self._data, self._data)
self._average = reduce(operator.add, self._data) / len(self._data)
self._sumsofquares = reduce(operator.add, self._Squares)
# blah blah blah
self._processed = 1
def minimize(self):
try:
del self._squares
del self._sumofsquares
# blah blah
except:
pass
my_packets = build_many_packets(100000)
do_hairy_stuff_with_packets(my_packets)
map(Packet.minimize, my_packets)
cPickle.dump(open("data.pickled", "w"))
(Only a little like that; what it actually does is a lot more
complicated.)
--
Gareth McCaughan Gareth.McCaughan at pobox.com
.sig under construc
More information about the Python-list
mailing list