开发者

Reason for uncommon OOP in Python?

Instead of using common OOP, like Java and C# do with their base class Object or object, Python uses special methods for basic behaviour of objects. Python uses __str__ which is used when the object is passed to print:

>>> class Demo:
>>>   def __str__(self):
>>>     return "representation"

>>> d = Demo()
>>> print(d)
representation

The same with len:

>>> cl开发者_开发知识库ass Ruler:
>>>   def __len__(self):
>>>     return 42

>>> r = Ruler()
>>> len(r)
42

What I would expect is something like this:

>>> class Ruler:
>>>   def len(self):
>>>     return 42

>>> r = Ruler()
>>> r.len()
42

What is the reason for using special methods indirectly instead of calling usual methods directly?


The reason for this is explained well in the Python documentation here:

http://docs.python.org/faq/design.html#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.

(This was answered in the comments, but needs to be shown as a real answer for the sake of future readers.)


These aren't hooks.

They're just methods with special names.

The convention for special method names in Python is __name__.

The built-in len, iter, str, repr (and other) functions use ordinary methods with names that follow a special convention so that we can all be sure we've implemented the special methods properly.

The special methods have odd-looking names so that we are free to use any name we want without fear of collision.


obj.len() would be much more intuitive to implement and use.

To you, perhaps. To others, it may be utterly baffling.

Python has both method notation and function notation for many common functions.

And the function notation is preferred.

It's still OO programming. Only the notation has been changed.


Hooks allow to redefine behavior of standard functions. Consider overriding __add__() and use standard infix + operator vs adding a custom add() and using nested calls.

Moreover, if you define __iter__(), you can use your object in a for ... in loop. Compare it to controlling a loop and advancing iteration by hand. Consider overriding __call__() and turning your instances into functions, as good as any other function. This gives enormous flexibility.

If you want, Java does the same with .toString() that works implicitly when you print the object or concatenate it to a string.


Not a Pythonista, so this may be way off, but if I understand your question, my impression is that it's a matter of style and idiom rather than behaviour. Java, and to a lesser extent C#, are very verbose, canonical and orthogonal languages. Everything is an object (or for C#, behaves like one--IIRC int.toString() is valid), and everything your program does should be explicitly expressed.

Python is more terse, valuing convenience at the occasional expense of clarity. You'll see this in C++ as well, with implicit conversions and operating overloading. Just consider the C++ analog to your toString() examples:

std::ostream& operator<<(std::ostream& outstream, const Widget& rhs)
{
    return outstream << rhs.name();
}

std::cout << myWidget;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜