Movatterモバイル変換


[0]ホーム

URL:


[Python-3000] Special methods and interface-based type system

Guido van Rossumguido at python.org
Wed Nov 22 21:09:31 CET 2006


On 11/22/06, Bill Janssen <janssen at parc.com> wrote:> Talking about the Abilities/Interfaces made me think about some of our> "rogue" special method names.  In the Language Reference, it says, "A> class can implement certain operations that are invoked by special> syntax (such as arithmetic operations or subscripting and slicing) by> defining methods with special names."  But there are all these methods> with special names like __len__ or __unicode__ which seem to be> provided for the benefit of built-in functions, rather than for> support of syntax.  Presumably in an interface-based Python, these> methods would turn into regularly-named methods on an ABC, so that> __len__ would become>>   class container:>     ...>     def len(self):>       raise NotImplemented>> Though, thinking about it some more, I don't see why *all* syntactic> operations wouldn't just invoke the appropriate normally-named method> on a specific ABC.  "<", for instance, would presumably invoke> "object.lessthan" (or perhaps "comparable.lessthan").  So another> benefit would be the ability to wean Python away from this> mangled-name oddness, which seems to me an HCI improvement.Hm. I'm not sure I agree (figure that :-).There are two bits of "Python rationale" that I'd like to explain first.First of all, I chose len(x) over x.len() for HCI reasons (def__len__() came much later). There are two intertwined reasonsactually, both HCI:(a) For some operations, prefix notation just reads better thanpostfix -- prefix (and infix!) operations have a long tradition inmathematics which likes notations where the visuals help themathematician thinking about a problem. Compare the easy with which werewrite a formula like x*(a+b) into x*a + x*b to the clumsiness ofdoing the same thing using a raw OO notation.(b) When I read code that says len(x) I *know* that it is asking forthe length of something. This tells me two things: the result is aninteger, 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 ofcontainer implementing an interface or inheriting from a class thathas a standard len(). Witness the confusion we occasionally have whena 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 youmeant that or not, but 'def len(self): ...' certainly sounds like youwant to demote it to an ordinary method. I'm strongly -1 on that.The second bit of Python rationale I promised to explain is the reasonwhy I chose special methods to look __special__ and not merelyspecial. I was anticipating lots of operations that classes might wantto override, some standard (e.g. __add__ or __getitem__), some not sostandard (e.g. pickle's __reduce__ for a long time had no support in Ccode at all). I didn't want these special operations to use ordinarymethod names, because then pre-existing classes, or classes written byusers without an encyclopedic memory for all the special methods,would be liable to accidentally define operations they didn't mean toimplement, with possibly disastrous consequences. Ivan Krstićexplained this more concise in his message, which arrived after I'dwritten all this up.-- --Guido van Rossum (home page:http://www.python.org/~guido/)


More information about the Python-3000mailing list

[8]ページ先頭

©2009-2026 Movatter.jp