I know that python has a len()
function that is used to determine the size of a string, but I was wondering why it's not a method of the string object.
Update
Ok, I realized I was embarrassingly mistaken. __len__()
is actually a method of a string object. It just seems weird to see object oriented code in Python using the len function on string objects. Furthermore, it's also weird to see __len__
as the name instead of just len.
There are some great answers here, and so before I give my own I'd like to highlight a few of the gems (no ruby pun intended) I've read here.
len
is actually an object. Ruby, on the other hand, doesn't have first class functions. So thelen
function object has it's own methods that you can inspect by runningdir(len)
.If you don't like the way this works in your own code, it's trivial for you to re-implement the containers using your preferred method (see example below).
Python is a pragmatic programming language, and the reasons for
len()
being a function and not a method ofstr
,list
,dict
etc. are pragmatic.The
len()
built-in function deals directly with built-in types: the CPython implementation oflen()
actually returns the value of theob_size
field in thePyVarObject
C struct that represents any variable-sized built-in object in memory. This is much faster than calling a method -- no attribute lookup needs to happen. Getting the number of items in a collection is a common operation and must work efficiently for such basic and diverse types asstr
,list
,array.array
etc.However, to promote consistency, when applying
len(o)
to a user-defined type, Python callso.__len__()
as a fallback.__len__
,__abs__
and all the other special methods documented in the Python Data Model make it easy to create objects that behave like the built-ins, enabling the expressive and highly consistent APIs we call "Pythonic".By implementing special methods your objects can support iteration, overload infix operators, manage contexts in
with
blocks etc. You can think of the Data Model as a way of using the Python language itself as a framework where the objects you create can be integrated seamlessly.A second reason, supported by quotes from Guido van Rossum like this one, is that it is easier to read and write
len(s)
thans.len()
.The notation
len(s)
is consistent with unary operators with prefix notation, likeabs(n)
.len()
is used way more often thanabs()
, and it deserves to be as easy to write.There may also be a historical reason: in the ABC language which preceded Python (and was very influential in its design), there was a unary operator written as
#s
which meantlen(s)
.You can also say
Using Python 2.7.3.
Jim's answer to this question may help; I copy it here. Quoting Guido van Rossum:
It doesn't?