CUBE SUGAR CONTAINER

技術系のこと書きます。

Python: Ellipsis について

今回は Python の特殊な定数 Ellipsis について調べてみた。

Ellipsis ってなんだ

Ellipsis というのは、主に拡張スライス文と共に使われる特殊な定数のこと。 これを使うと、例えば配列などのスライスで「...」を指定できるようになる。

3. 組み込み定数 — Python 3.5.2 ドキュメント

具体的な使用例

例えば、高速な数値計算のための配列ライブラリである NumPy の配列には、この Ellipsis を使うことができる。

ひとまず NumPy をインストールしよう。

$ pip install numpy

そして Python の REPL を起動する。

$ python

array という名前で NumPy の配列を作る。

>>> import numpy as np
>>> array = np.array([1, 2, 3])

この配列のスライスに「...」を指定してみよう。 これが Ellipsis だ。

>>> array[...]
array([1, 2, 3])

NumPy では (その次元の) すべての要素を返すことを表すために使われている。

ユーザ定義クラスで Ellipsis を使ってみる

ユーザ定義クラスで Ellipsis を指定できるようにしてみよう。 まず、ユーザ定義クラスでは __getitem__() という特殊メソッドを実装すると、そのインスタンスにスライス ([]) が使えるようになる。 そのメソッドに渡されるキーとして Ellipsis が指定されたら「...(snip)...」という値を返すようにしてみる。

#!/usr/bin/env python
# -*- coding: utf-8 -*-


class MyClass(object):

    def __getitem__(self, key):
        if key is Ellipsis:
            return '...(snip)...'

        return None


def main():
    obj = MyClass()
    print(obj[...])


if __name__ == '__main__':
    main()

上記を ellipsis.py という名前で保存して実行してみよう。

$ python ellipsis.py
...(snip)...

ばっちり。

Python 2 と 3 における Ellipsis の振る舞い

実は Ellipsis は Python 2.x と 3.x で振る舞いが結構違っている。 それぞれのインタプリタで挙動の違いを確かめてみよう。

まずは Python 3.x から。

$ python --version
Python 3.5.1
$ python

Python 3.x では「...」が単独で Ellipsis オブジェクトとして使える。

>>> ...
Ellipsis

それ対し Python 2.x ではどうなるだろうか。

$ python --version
Python 2.7.10
$ python

なんと「...」だけでは文法エラーになってしまった。

>>> ...
  File "<stdin>", line 1
    ...
    ^
SyntaxError: invalid syntax

Python 2.x では Ellipsis の使えるシチュエーションが、とても限られていることがわかる。

例えば、次のように通常のメソッドの引数として Ellipsis を受け取るようにしてみよう。

#!/usr/bin/env python
# -*- coding: utf-8 -*-


class MyClass(object):

    def mymethod(self, value):
        if value is Ellipsis:
            return '...(snip)...'

        return None


def main():
    obj = MyClass()
    print(obj.mymethod(...))


if __name__ == '__main__':
    main()

これを、先ほどと同じように ellipsis.py という名前で保存する。 まずは Python 3.x で動かしてみよう。

$ python --version
Python 3.5.1
$ python ellipsis.py
...(snip)...

ちゃんと動いた。

それに対し Python 2.x だと、どうなるだろうか。

$ python --version
Python 2.7.10
$ python ellipsis.py
  File "ellipsis.py", line 16
    print(obj.greeting(...))
                       ^
SyntaxError: invalid syntax

こちらは文法エラーになってしまった。 通常のメソッドの呼び出しに Ellipsis は渡すことができないらしい。

まとめ

  • Ellipsis は「...」を表す特殊な定数
  • Python 2 と 3 では挙動が異なる
  • Python 3 では「...」が Ellipsis オブジェクトになっている
  • そのため、通常のメソッドの引数などにも Ellipsis が使える
  • それに対し Python 2 では拡張スライス文でしか使えない