2016-09-11 3 views
6
난 그냥 슬라이스를 지원하기 위해이있는 library에 대한 테스트 커버리지를 개선했고 나는 조각이 아닌 정수형 포함 할 수있는 것으로 나타났습니다

:파이썬 조각에 내장 된 내장 형식이 아닌 이유는 무엇입니까?

>>> 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 및 사용하는 숫자 형식은 개체에서 상속받을 수 없으므로 전달 된 형식의 검사가 인덱스 값으로 사용할 수 없게됩니다. 따라서 오리 타이핑을 사용하면 적절한 방법 (__index__)을 정의하면 유용합니다.

PySlice_GetIndicesEx이 시도하고 값 당신을 얻기 위해 호출되는 작업 (당신이 본대로 TypeError에서, __getitem__ 동안 즉 list_subscript을 제기했다) 슬라이스를 적용 할 때 또한이 (__index__의 존재)에만 적용됩니다 유의을 통과했다. 예에서는 슬라이스가 무효

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

이전 PEP 357에 있었다 :

slice objects initializer은들로 적용 할 수있는 모든 PyObject '는 서명에서 볼 수있는, 그것을 받아들이는 유형에 차별을하지 않습니다?

난 그냥 인수가 초기화하는 동안 수행되지 숫자하지만 만약 __getitem__가 호출 될 때 다시 검사를 (내가 잘못 아니에요 경우 PEP 3572.5 등장) 파이썬의 2.4 버전을 구축하고 테스트;

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__ 던더에 대한 통지를하지 않는 예외 메시지입니다 , 핵심 언어가 정수 또는 정수형 객체 (즉, 유형이 __index__ 메소드를 제공하는 객체)만을 조각에 사용하도록 제 3 자 라이브러리를 제한 할 이유가 없습니다. 여기에 슬라이스에 비 정수를 사용하여 패키지의 두 가지 주목할만한 예는 다음과 같습니다 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 

정수가 아닌 슬라이스를 생성 할 때 코어 언어가 예외를 발생시키는 것은 이해가되지 않습니다. 위의 라이브러리가 손상 될 수 있습니다. 대신 슬라이스 구성 요소 (시작, 중지, 단계)가 적절한 유형이 아니면 실제 슬라이싱 작업에서 예외가 발생해야합니다.

관련 문제