2016-09-11 34 views
6

私はちょうどスライスをサポートする必要があると私はスライスが非整数型を含めることができることに気付きましたlibraryのためのテストカバレッジを向上しました:pythonスライスに組み込まれていない組み込み型以外はなぜですか?

>>> slice(1, "2", 3.0) 
slice(1, '2', 3.0) 
>>> sl = slice(1, "2", 3.0) 
>>> [1,2,3][sl] 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: slice indices must be integers or None or have an __index__ method 

これはちょうど私の静的型付けの背景かもしれないが、それはそうです私には、__index__のない組み込み型はTypeErrorなしでここに渡すことができます。なぜこれはそうですか? __index__を実装するタイプのダックタイピングをサポートするために、任意のタイプが許可されていると仮定して正しいでしょうか?最も一般的に使用されるケースのパフォーマンス上の理由により、タイプチェックが欠けていますか?

PEP 357より前の例ではスライスが無効でしたか?

+0

floatを使用したスライス構文は、n次元空間内の境界ボックスを効率的に記述することができます。これは、場合によっては便利なことがあります。カスタムタイプは、そのようなスライスを受け入れることができます。 – Kevin

+0

これは私が考えていなかったフロートの本当に面白い使用例です。文字列はなぜ許可されますか? – shuttle87

+1

スライスで[省略記号](http://stackoverflow.com/questions/772124/what-does-the-python-ellipsis-object-do)を使用することもできます。 –

答えて

2

__index__を実装するタイプのダックタイピングをサポートするには、任意のタイプが許可されていると思いますか?

sliceオブジェクトを初期化するときに渡される型を制限する理由は何もありません。正確にPEP 357の合理的な記述の通り、numpyとそれが利用する数値型はオブジェクトから継承できないので、渡された型の厳密なissubclassチェックはインデックス値として使用できなくなります。ダックタイピングが採用されているので、適切なメソッド(__index__)が定義されていれば使用できます。

PySlice_GetIndicesExを試してみて、値にあなたを取得するために呼び出される操作(あなたが見たように、TypeErrorは、__getitem__中にすなわちlist_subscriptを上げた)スライスを適用する際にも、この(__index__の存在は)のみ施行されていることに注意を要します合格。

slice objects initializerは、その署名から分かるように、sが適用できるすべてのPyObject」は受け入れ種類に差別をしない:前PEP 357

PyObject * 
PySlice_New(PyObject *start, PyObject *stop, PyObject *step) 
{ 
    /* rest omitted */ 

は無効例では、スライスでしたか?

私はただのPythonの2.4バージョンを構築し、それをテストした(PEP 357私は間違っていない場合2.5に登場)、再びチェック引数が数値である場合には、初期化時に行われていないが、__getitem__が呼び出されたとき。

Python 2.4 (#1, Sep 11 2016, 18:13:11) 
[GCC 5.4.0 20160609] on linux4 
Type "help", "copyright", "credits" or "license" for more information. 
>>> s = slice(0, Ellipsis) 
>>> [1, 2, 3][s] 
Traceback (most recent call last): 
    File "<stdin>", line 1, in ? 
TypeError: slice indices must be integers 
4

サードパーティのライブラリは、独自のオブジェクトに対してスライスを実装することもできます。異なり唯一のものは、(その後、明らかに存在していなかった)__index__ dunderについて予告をしない例外メッセージですこれらのサードパーティのライブラリを、整数や整数のようなオブジェクト(つまり、型が__index__メソッドを提供するオブジェクト)だけをスライスに使用するように制限する理由はありません。ここでは、スライスに非整数を使用してパッケージの2顕著な例は以下のとおりですnumpyの中で、いくつかのオブジェクトは、例えば、複雑なステップを受け入れる:

>>> import numpy 
>>> numpy.mgrid[0:2:5j] 
array([ 0. , 0.5, 1. , 1.5, 2. ]) 

そしてパンダで

は、あなたがラベルによって Seriesまたは Dataframeオブジェクトをスライスすることができます。そのラベルは文字列、または datetimeオブジェクト(たとえば)です。

>>> import pandas 
>>> s = pandas.Series(range(4), index=['a', 'b', 'c', 'd']) 
>>> s['b':'d'] 
b 1 
c 2 
d 3 
dtype: int64 

したがって、非整数を含むスライスを構築するときにコア言語が例外を発生させるのは意味がありません。上記のライブラリを破壊するでしょう。その代わりに、スライスコンポーネント(start、stop、step)が適切な型でない場合、実際のスライス操作で例外が発生するはずです。

関連する問題