The Python standard library and PEP8
emmanuel.surleau at gmail.com
Mon Apr 20 18:55:42 CEST 2009
On Monday 20 April 2009 10:55:19 Steven D'Aprano wrote:
> On Mon, 20 Apr 2009 08:05:01 +0200, Emmanuel Surleau wrote:
> > On Monday 20 April 2009 01:48:04 Steven D'Aprano wrote:
> >> It also depends on whether you see the length of a data structure as a
> >> property of the data, or the result of an operation ("counting") on the
> >> data structure. We often fall into the trap of saying such things as
> >> "the string HAS A length of 42" when what we really mean is "if you
> >> count the elements of the string we find 42 of them". I don't believe
> >> that the relationship between strings and length is a has-a
> >> relationship. I believe it is a property requiring a function
> >> (counting) to emerge, and therefore under OO principles, length
> >> *not* be an attribute and Java et al are guilty of misuse of OO in
> >> making length an attribute.
> > This didn't quite make sense. Methods are "abilities" an object has. Why
> > shouldn't a string be able to compute its length?
> Nothing. I'm not talking about methods, I'm talking about making length a
> property (or attribute if you prefer).
> I must admit a mistake: Java does not treat the length of a string as an
> attribute, but uses a callable method, String.length(), so I withdraw my
> accusation of misuse of OO principles.
Well, Java uses .length on arrays (but arrays are not really objects). But
most constants are hidden behind accessors or "regular" methods.
> > As noted above, nothing would stop Fred from having the ability to
> > "computeHeight()", though. I guess you could say that what I find silly
> > is that String objects have a number of abilities, which: - are more
> > complicated than retrieving their own length - most likely use len()
> > internally anyway
> Advantages of calling a length method:
> - Consistency with other methods.
> - Makes it easy to discover by introspection.
> Disadvantages of calling a length method:
> - In Python for built-in lists, tuples and strings, it requires at least
> one extra attribute lookup that the len() function doesn't need. (Java
> can avoid paying that cost at runtime by doing it at compile time -- this
> isn't available to Python.)
Someone on the list pointed out that that Python actually stores the length of
a string in a field for performance reasons. I wouldn't be surprised to hear
that the same is true for lists and tuples. Thoughts?
> - It makes it more difficult to write functional code such as this:
> map(len, [seq1, seq2, seq3])
> where the various seq* are arbitrary sequences, not necessarily just
> strings. (Functional in the sense of functional-programming, not in the
> sense of "it works".)
That's a good point.
> - It makes it harder to intercept calls to len() for debugging. I can do
> def len(obj):
> print "called len with arg %r" % obj # or log it somewhere
> return __builtins__.len(obj)
> and have all the calls to len go through that, without even knowing what
> type of object is being called.
> But note that because len() in turn calls obj.__len__ (unless obj is a
> known built-in like str), you keep all the advantages of OO methods like
> sub-classing, without any of the disadvantages.
Both arguments hold true for any method, though.
> > And yet, when asked, it's not able to do something as basic as tell its
> > length. This seems inconsistent to me.
> Well, you can do this:
> >>> s = "abc"
> >>> s.__len__()
> but if you do it in public, be prepared to have other Python programmers
> laugh at you.
I do understand that you don't call __xxx__ without a good reason.
> It's just a stylistic difference, it's not a functional difference. Even
> if there is a genuine, objective advantage to one approach over the other
> (and I believe that advantage goes to len() as a function), it's quite
> small and it won't really make that big a difference.
Well, Aahz and Carl Banks managed to convince me that len() has legitimate
reasons to exist, and I can live with that. Thanks for providing some
examples of functional code where len() as a function is more interesting
than len() as a method.
More information about the Python-list