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.
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.
Strings do have a length method:
The protocol in Python is to implement this method on objects which have a length and use the built-in
len() function, which calls it for you, similar to the way you would implement
__iter__() and use the built-in
iter() function (or have the method called behind the scenes for you) on objects which are iterable.
See Emulating container types for more information.
Here's a good read on the subject of protocols in Python: Python and the Principle of Least Astonishment
Jim's answer to this question may help; I copy it here. Quoting Guido van Rossum:
First of all, I chose len(x) over x.len() for HCI reasons (def __len__() came much later). There are two intertwined reasons actually, both HCI:
(a) For some operations, prefix notation just reads better than postfix — prefix (and infix!) operations have a long tradition in mathematics which likes notations where the visuals help the mathematician thinking about a problem. Compare the easy with which we rewrite a formula like x*(a+b) into xa + xb to the clumsiness of doing the same thing using a raw OO notation.
(b) When I read code that says len(x) I know that it is asking for the length of something. This tells me two things: the result is an integer, and the argument is some kind of container. To the contrary, when I read x.len(), I have to already know that x is some kind of container implementing an interface or inheriting from a class that has a standard len(). Witness the confusion we occasionally have when a class that is not implementing a mapping has a get() or keys() method, or something that isn’t a file has a write() method.
Saying the same thing in another way, I see ‘len‘ as a built-in operation. I’d hate to lose that. /…/