python without OO

John Hunter jdhunter at ace.bsd.uchicago.edu
Wed Jan 26 23:28:10 EST 2005


>>>>> "beliavsky" == beliavsky  <beliavsky at aol.com> writes:

    beliavsky> I think the OO way is slightly more obscure. It's
    beliavsky> obvious what x = reverse(x) does, but it is not clear
    beliavsky> unless you have the source code whether x.reverse()

You don't need to read the src, you just need to read the docs

  >>> help([].reverse)
  Help on built-in function reverse:

  reverse(...)
      L.reverse() -- reverse *IN PLACE*

    beliavsky> reverses x or if it returns a reversed list. If
    beliavsky> x.reverse() does the former, a disadvantage relative to
    beliavsky> the procedural approach is that a function can be used
    beliavsky> in an expression. It is clearer and more concise to
    beliavsky> write

    beliavsky> z = reverse(x) + reverse(y)

The distinction is not OO versus procedural, it is a decision about
how you choose to write "reverse".  The python list implementers of
the reverse object method could have decided to return a new reversed
list rather than do the reverse in place and return None.  Then you
could have done

  z = x.reverse() + y.reverse()

They could have chosen to reverse the list *in place* and also
returned a reference to self rather than None, in which case you could
do the above as well.  w/o digging up the transcripts from the
python-dev mailing list, my guess is that they choose to do it in
place for efficiency in memory and cpu, and chose not to return self
to prevent user confusion.  Ie, if a user was allowed to do 'z =
x.reverse() + y.reverse()' they might be surprised to find the side
effect of in place modification.

Likewise, I could easily write a procedural "in place" reverse that
returns None, in which case 'z = reverse(x) + reverse(y)' would not do
what you suggest.  My point is that whether a function/method such as
reverse operates in place or on a copy, and whether it returns None or
a reference to a list is independent of OO vs procedural style and is
motivated by considerations of efficiency, readability, and usability.

    beliavsky> Furthermore, if in Python the algorithm for the reverse
    beliavsky> function applies to many kinds of objects, it just
    beliavsky> needs to be coded once, whereas a reverse method would
    beliavsky> have to provided for each class that uses it (perhaps
    beliavsky> through inheritance).

True, a generic reverse procedure/function can be applied to any data
structure that supports iteration.  In the case of python, however,
some iterable data structures are mutable (lists, dicts) and some are
not (strings, tuples).  For mutable sequences, an in place reverse is
likely to be more efficient in memory and perhaps CPU than a generic
reverse which returns a new copy.  So a specialized method "reverse"
applicable to lists (but not strings and tuples) can be a big win.
Fortunately, python supports both, allowing you to define a general
"reverse" that works for any object that supports the sequence
protocol, as well as to define an object specific reverse method that
may be faster in time and space.   

JDH




More information about the Python-list mailing list