methaneのブログ

このブログに乗せているサンプルコードはすべてNYSLです。

演算子オーバーライド

オーバーライドという単語が適切かどうかは微妙だけど、昨日言ってた__len__()の話。

len(x)は、内部的には以下のような動作になっている。

def len(x):
  return x.__len__()

だから、len(x)が返す値は、xの実装に依存する。

>>> class Foo:
...   def __init__(s):
...     pass
...
>>> f = Foo()
>>> len(f)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
AttributeError: Foo instance has no attribute '__len__'
>>> class Bar:
...   def __len__(s):
...     return 5
...
>>> b = Bar()
>>> len(b)
5
>>>

このように、x.len()ではなくlen(x)になっているといっても、内部的にはx.__len__()であり、きちんとポリモーフィズムが成り立っている。

昨日言っていた予約語の話は、len()を定義したい人以外が、いちいち「lenが特殊なキーワードである」といったことを暗記しなくても良い(lenというメンバ変数を持っても問題ない)から、大量の「特殊キーワード一覧」を覚えなくても使えてとっつきやすいよね、ということ。
もちろん、さらにPythonに踏み込んでいくには、__len__()、__str__()、__init__()、etc...を覚えていかないといけない。
でも、ラーニングカーブの緩やかさは、Pythonの美点の一つである。