Pythonコードが長さメソッドの代わりにlen()関数を使用するのはなぜですか?

StackOverflow https://stackoverflow.com/questions/237128

質問

pythonには文字列のサイズを決定するために使用される len()関数があることは知っていますが、なぜそれが文字列オブジェクトのメソッドではないのか疑問に思っていました。

更新

わかりました、私は恥ずかしいほど間違っていることに気付きました。 __ len __()は、実際には文字列オブジェクトのメソッドです。 Pythonで文字列オブジェクトにlen関数を使用するオブジェクト指向コードを見るのは奇妙に思えます。さらに、名前としてlenだけではなく __ len __ を見るのも奇妙です。

役に立ちましたか?

解決

文字列にはlengthメソッドがあります: __ len __()

Pythonのプロトコルは、長さを持ち、組み込みの len() 関数。これは、 __ iter __()を実装する方法と同様に、それを呼び出しますそして、反復可能なオブジェクトに対して組み込みの iter()関数を使用します(または、背後でメソッドを呼び出します)。

詳細については、コンテナタイプのエミュレーションをご覧ください。

Pythonのプロトコルの主題に関する良い読み物です: Pythonと最小驚きの原理

他のヒント

この質問に対するJimの回答が役立つ場合があります。ここにコピーします。 Guido van Rossumの引用:

  

まず、HCIの理由から、x.len()よりもlen(x)を選択しました(def __len __()はかなり後のことです)。実際には2つの理由が絡み合っています。どちらもHCIです。

     

(a)一部の操作では、プレフィックス表記はpostfix—よりも読みやすくなります。接頭辞(および中置!)操作は、数学の長い伝統があり、ビジュアルが問題についての数学者の思考を助ける表記法を好む。 x *(a + b)のような式をx a + x bに書き換える簡単さと、生のOO表記を使用して同じことを行う不器用さを比較してください。

     

(b)len(x)というコードを読んだとき、何かの長さを要求していることがわかります。これにより、2つのことがわかります。結果は整数であり、引数は何らかのコンテナです。それどころか、x.len()を読むとき、xはインターフェースを実装するか、標準のlen()を持つクラスから継承する何らかのコンテナであることをすでに知っている必要があります。マッピングを実装していないクラスにget()またはkeys()メソッドがある場合や、ファイルにwrite()メソッドがない場合にときどき生じる混乱を目撃してください。

     

同じことを別の方法で言うと、‘ len‘組み込み操作として。それを失うのは嫌だ。 /… /

len メソッドがあります:

>>> a = 'a string of some length'
>>> a.__len__()
23
>>> a.__len__
<method-wrapper '__len__' of str object at 0x02005650>

Pythonは実用的なプログラミング言語であり、 len() str list のメソッドではなく関数である理由、 dict などは実用的です。

len()組み込み関数は組み込み型を直接処理します。 len()のCPython実装は、実際には ob_sizeの値を返します PyVarObject C構造体フィールド>メモリ内の可変サイズの組み込みオブジェクトを表します。これは、メソッドを呼び出すよりもずっと高速です。属性のルックアップを行う必要はありません。コレクション内のアイテムの数を取得することは一般的な操作であり、 str list array.array など

ただし、一貫性を高めるため、ユーザー定義型に len(o)を適用する場合、Pythonはフォールバックとして o .__ len __()を呼び出します。 __ len __ __ abs __ 、およびに記載されている他のすべての特別なメソッドPython Data Model を使用すると、組み込みのように動作するオブジェクトを簡単に作成できるため、「Pythonic」と呼ばれる表現力豊かで一貫性のあるAPIを使用できます。

特別なメソッドを実装することで、オブジェクトは反復をサポートし、中置演算子をオーバーロードし、 ブロックでコンテキストを管理できます。データモデルは、使用方法と考えることができます。作成したオブジェクトをシームレスに統合できるフレームワークとしてのPython言語自体。

これは、よりも len(s)の読み取りと書き込みが簡単なことです。 s.len()

len(s)という表記は、 abs(n)のようなプレフィックス表記の単項演算子と一致しています。 len()は、 abs()よりも頻繁に使用され、簡単に書くことができます。

歴史的な理由もあるかもしれません:Pythonに先行するABC言語(およびその設計に非常に影響を与えた)には、 lenを意味する #s と書かれた単項演算子がありました(s)

met% python -c 'import this' | grep 'only one'
There should be one-- and preferably only one --obvious way to do it.

ここには素晴らしい答えがいくつかあるので、自分で説明する前に、いくつかの宝石を紹介したいです(ルビーをしゃべるつもりはありません)。ここで読みました。

  • Pythonは純粋なOOP言語ではありません-汎用のマルチパラダイム言語であり、プログラマーが最も快適なパラダイムやソリューションに最適なパラダイムを使用できるようにします。
  • Pythonには一流の関数があるため、 len は実際にはオブジェクトです。一方、Rubyにはファーストクラスの関数はありません。したがって、 len 関数オブジェクトには独自のメソッドがあり、 dir(len)を実行することで検査できます。

独自のコードでこれが機能する方法が気に入らない場合は、好みの方法を使用してコンテナを再実装するのは簡単です(以下の例を参照)。

>>> class List(list):
...     def len(self):
...         return len(self)
...
>>> class Dict(dict):
...     def len(self):
...         return len(self)
...
>>> class Tuple(tuple):
...     def len(self):
...         return len(self)
...
>>> class Set(set):
...     def len(self):
...         return len(self)
...
>>> my_list = List([1,2,3,4,5,6,7,8,9,'A','B','C','D','E','F'])
>>> my_dict = Dict({'key': 'value', 'site': 'stackoverflow'})
>>> my_set = Set({1,2,3,4,5,6,7,8,9,'A','B','C','D','E','F'})
>>> my_tuple = Tuple((1,2,3,4,5,6,7,8,9,'A','B','C','D','E','F'))
>>> my_containers = Tuple((my_list, my_dict, my_set, my_tuple))
>>>
>>> for container in my_containers:
...     print container.len()
...
15
2
15
15

また言うことができます

>> x = 'test'
>> len(x)
4

Python 2.7.3を使用します。

違いますか?

>>> "abc".__len__()
3
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top