views:

171

answers:

6

What's the reason of providing some of the default methods in the global scope, like the len function, instead of providing them on an instance level, like:

list.len()

instead of:

len (list)

I find methods like len to be harder to discover than instance methods.

Is there any reason behind this?

A: 

You can write

re.match(r"\w+", "dog")

instead of

pattern = re.compile(r"\w+")
pattern.match("dog")

Like You noticed, sometimes it doesn't make sense.

Jacek Ławrynowicz
I don't see how this answers the question.
Kiv
The reason of providing some of the default methods in the global scope is to enable devloper to use shortcuts in common tasks.
Jacek Ławrynowicz
+2  A: 

Once you learn the "len" method, you know you can apply it to any sequence. You don't have to read the doc for each sequence you encounter to find out whether or not it has a len method. There's an expectation that it does.

Built-in functions are not harder to discover because there's a list of built-in methods in the python documentation. You can learn them all in one sitting from this page instead of having to hunt for them all over the class library Java style.

Seun Osewa
+4  A: 

This FAQ entry might answer your question:

4.7 Why does Python use methods for some functionality (e.g. list.index()) but functions for other (e.g. len(list))?

The major reason is history. Functions were used for those operations that were generic for a group of types and which were intended to work even for objects that didn't have methods at all (e.g. tuples). It is also convenient to have a function that can readily be applied to an amorphous collection of objects when you use the functional features of Python (map(), apply() et al).

In fact, implementing len(), max(), min() as a built-in function is actually less code than implementing them as methods for each type. One can quibble about individual cases but it's a part of Python, and it's too late to make such fundamental changes now. The functions have to remain to avoid massive code breakage.

Note that for string operations Python has moved from external functions (the string module) to methods. However, len() is still a function.

There is a list of all those functions (not too many) here in the docs.

MrTopf
+6  A: 

This question is very similar to this one. And the answers is the same:

Because Guido van Rossum, the creator of Python, thinks that prefix notation is more readable in some cases. Here is the complete answer. I'm going to quote some parts:

(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 x*a + x*b 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. I can't say for sure whether you meant that or not, but 'def len(self): ...' certainly sounds like you want to demote it to an ordinary method. I'm strongly -1 on that.

Manuel Ceron
ah, I missed this and I was wondering why len() is actually still available in Python 3.
MrTopf
+2  A: 

Besides the FAQ answer provided by MrTopf, lists (and other objects) do have a length method __len__()

The len() function is just a shorthand for calling that method.

Van Gale
A: 

They are fairly discoverable:

>>> import __builtin__
>>> dir(__builtin__)
['ArithmeticError', 'AssertionError', ...
...

or better

>>> help(__builtin__)

Help on built-in module __builtin__:

NAME
    __builtin__ - Built-in functions, exceptions, and other objects.
...
davidavr