Pages - Menu

Pages - Menu

Pages

2023年1月4日水曜日

なぜPythonのlen関数はメソッドになっていないのですか?

https://jp.quora.com/%E3%81%AA%E3%81%9CPython%E3%81%AElen%E9%96%A2%E6%95%B0%E3%81%AF%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%81%AB%E3%81%AA%E3%81%A3%E3%81%A6%E3%81%84%E3%81%AA%E3%81%84%E3%81%AE%E3%81%A7%E3%81%99%E3%81%8B

[Python-3000] Special methods and interface-based type system
[Python-3000] Special methods and interface-based type system Guido van Rossum guido 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 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 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. The second bit of Python rationale I promised to explain is the reason why I chose special methods to look __special__ and not merely special. I was anticipating lots of operations that classes might want to override, some standard (e.g. __add__

Iriedaさんがリンクしてますが、いちおう私の努力訳

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:

まず、私がx.len()よりもlen(x)を選んだのはHCI的理由からです(def __len__()はもっとあとから来ました。2つ絡み合った理由がありますが、どちらも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 x*a

… (もっと読む)
 · 
フォロー

こういう統一性のなさは、実用的なスクリプト言語ではよくあることです。

Pythonも最初から高度に(美しく)統一されたオブジェクト指向を目指していたわけではないため、楽にスクリプトが組めるよう、よく使われる処理はグローバル関数として実装されているものがあります。実用性のために統一性のない実装を許容していたのですね。

PHPなんかはその極端な例で、ほとんどの機能が標準関数で実装されており、関数の命名規則によって何に対する処理(arrayやstrなど)なのかがわかるように分類されています。PHPはWeb開発(バックエンド)でいまだにトップのシェアを誇るスクリプト言語ですので、あれこれ言われつつ、なんだかんだ標準の関数でどこでも使える方が便利に楽に書ける、というのは真理なのかもしれません。

 · 
フォロー

Golangもそうなってますね、GoはOOPを推奨してないのでわかりますが、Pythonがlen関数な理由はこれだ!と言うのは思いつかないですね。

C++でtemplateで受け取ったもののサイズが欲しいとか、javaで配列とCollection別に関数作らなきゃならないのを見ると、

動的型付けで引数にどんな型が入ってくるか解らないなら、実装に左右されずlen関数でサイズを取得できるので、固定されてる方がいい気がしますね。

まぁ単純に、最初は文字列も配列も自分のサイズを持っていない実装で、builtinのlen関数で毎回サイズを計算していたとかな気がしますけどね。

あとはOOPを取り入れるつもりがなかったとか、Pythonのクラスってselfを引数に取ったり、抽象化にABCMetaとかいう謎のパッケージが必要だったり、どうにかなんなかったのか!と言いたくなる仕様多いですからね。

0 件のコメント:

コメントを投稿