回答:
lenコレクションの長さを取得する関数です。オブジェクトの__len__メソッドを呼び出すことで機能します。__something__属性は特別であり、通常は見た目以上のものであり、通常は直接呼び出さないでください。
それはずっと前という推論、何かの長さが機能していないメソッドコードでなければなりません取得いくつかの時点で決まったlen(a)の意味が初心者には明らかであるだろうが、a.len()明らかようではありません。Pythonが始まっ__len__た頃は存在していなかったlenし、いくつかのタイプのオブジェクトで機能する特別なものでした。これが私たちに残している状況が完全に理にかなっているかどうかに関係なく、それはとどまることです。
多くの場合、組み込みまたは演算子の「典型的な」動作は、__whatever__関係するオブジェクトに対して適切なマジックメソッド(のような名前を持つもの)を(異なる、より良い構文で)呼び出すことです。多くの場合、組み込みまたは演算子は「付加価値」を持っています(関係するオブジェクトに応じて異なるパスをとることができます)len-vs の場合__len__、組み込みに欠けているのは組み込みの少しの妥当性チェックだけです魔法の方法:
>>> class bah(object):
... def __len__(self): return "an inch"
...
>>> bah().__len__()
'an inch'
>>> len(bah())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object cannot be interpreted as an integer
あなたはへの呼び出しを参照するとlen、内蔵あなたがしている、必ずプログラムはその後続けば、むしろ例外を発生させるよりも、呼び出しは整数、非負、未満2 ** 31を返した、ということ-ときへの呼び出しが表示されxxx.__len__()、確実ではありません(コードの作成者がPythonに慣れていないか、まったく役に立たない場合を除きます;-)。
他のビルトインは、単純な健全性チェックと読みやすさを超える、さらに付加価値を提供します。ビルトインの呼び出しと演算子の使用を介して、マジックメソッドの呼び出しを介さずに機能するようにすべてのPythonを均一に設計することにより、プログラマーはどちらのケースかを覚える負担から解放されます。(エラーが発生する場合があります:2.5までは呼び出す必要がありfoo.next()ました-2.6でも下位互換性のために機能しますが、を呼び出す必要がありますnext(foo)。また3.*、魔法のメソッドには__next__"oops-ey"ではなく正しく名前が付けられていますnext!- )。
したがって、原則として、マジックメソッドを直接呼び出さないようにする必要があります(ただし、組み込みメソッドを介して間接的に常に呼び出す必要があります)。これを行う必要がある理由が正確にわかっている場合を除きます(たとえば、サブクラスでこのようなメソッドをオーバーライドする場合、サブクラスは、マジックメソッドへの明示的な呼び出しを通じて実行する必要があるスーパークラスに従う必要があります)。
def len(x): return "I am a string." print(len(42)) print(len([1,2,3]))そしてそれはI am string2回印刷されました。もっと詳しく説明してもらえますか?
__len__特別なメソッドを呼び出す組み込みlenについて話しました。
lenたまたま同じ名前を持つ他の関数(例のように)ではなく、組み込み関数を呼び出していることを確認するにはどうすればよいですかlen。「組み込み関数lenを再定義しています」などの警告は表示されません。私の意見では、アレックスが彼の答えで述べたことについて確信が持てません。
len in vars(__builtins__).values()。
len()はおおよそ次と同等であると考えることができます
def len(x):
return x.__len__()
1つの利点は、次のようなものを記述できることです。
somelist = [[1], [2, 3], [4, 5, 6]]
map(len, somelist)
の代わりに
map(list.__len__, somelist)
または
map(operator.methodcaller('__len__'), somelist)
ただし、動作が少し異なります。たとえば、intの場合
>>> (1).__len__()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'int' object has no attribute '__len__'
>>> len(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: object of type 'int' has no len()
operator.methodcaller代わりにあなたが意味すると思いますoperator.attrgetter。
あなたはPythondドキュメントをチェックすることができます:
>>> class Meta(type):
... def __getattribute__(*args):
... print "Metaclass getattribute invoked"
... return type.__getattribute__(*args)
...
>>> class C(object):
... __metaclass__ = Meta
... def __len__(self):
... return 10
... def __getattribute__(*args):
... print "Class getattribute invoked"
... return object.__getattribute__(*args)
...
>>> c = C()
>>> c.__len__() # Explicit lookup via instance
Class getattribute invoked
10
>>> type(c).__len__(c) # Explicit lookup via type
Metaclass getattribute invoked
10
>>> len(c) # Implicit lookup
10