문자열은 이렇게 대답은 당신이 많은 약 c과 python-c-api를 모르면 이해하기 위해 그 솔직하지 c 구현하지만, 어쨌든 최선을 다할된다
직접 __getslice__
를 호출하는 경우 당신은 string_slice
를 사용합니다 :
static PyObject *
string_slice(PyStringObject *a, Py_ssize_t i, Py_ssize_t j)
/* j -- may be negative! */
{
if (i < 0)
i = 0;
if (j < 0)
j = 0; /* Avoid signed/unsigned bug in next line */
if (j > Py_SIZE(a))
j = Py_SIZE(a);
if (i == 0 && j == Py_SIZE(a) && PyString_CheckExact(a)) {
/* It's the same as a */
Py_INCREF(a);
return (PyObject *)a;
}
if (j < i)
j = i;
return PyString_FromStringAndSize(a->ob_sval + i, j-i);
}
여기
i
는 시작 인덱스와 j
는 정지 인덱스입니다. 정지가 0보다 작은 경우 0
(if (j < 0) j = 0;
)으로 설정되고 시작보다 작기 때문에 시작 (if (j < i) j = i;
)으로 설정됩니다. 따라서 start = 10으로 끝나고 stop = 10으로 끝납니다. 이것은 빈 문자열입니다.
하지만 []
를 사용하는 경우는 (내가 그 방법의 관련 부분을 포함 단지 것) string_subscript
전화 할게 :
이
static PyObject*
string_subscript(PyStringObject* self, PyObject* item)
{
/* ... */
if (PySlice_Check(item)) {
Py_ssize_t start, stop, step, slicelength, cur, i;
/* ... */
if (_PySlice_Unpack(item, &start, &stop, &step) < 0) {
return NULL;
}
slicelength = _PySlice_AdjustIndices(PyString_GET_SIZE(self), &start,
&stop, step);
/* ... */
if (step == 1) {
return PyString_FromStringAndSize(
PyString_AS_STRING(self) + start,
slicelength);
}
/* ... */
}
/* ... */
}
제대로는 _PySlice_AdjustIndices
와 인덱스를 (이 PySlice_AdjustIndices
처럼) 조정합니다. 즉, 함수 len(string) - 1
의 정지 -1의 조리개를 변환한다 :
Py_ssize_t PySlice_AdjustIndices (Py_ssize_t 길이 Py_ssize_t * 시작 Py_ssize_t * 정지 Py_ssize_t 공정)
조정 시작/종료 슬라이스 인덱스 지정된 길이의시 v 스를 가정합니다. 범위를 벗어난 인덱스는 정상 슬라이스의 처리와 일관된 방식으로 잘립니다.
실제로 호출되는 함수는 해당 함수와 다를 수 있습니다. 그러나이 문서는 두 가지 모두에 적용됩니다.
그러나 일반적으로 __*__
메서드는 직접 호출하면 안됩니다. 따라서 파이썬에서 버그인지 또는 의도 된 사용인지는 알 수 없습니다 (특정 종류의 슬라이스에 대해 내가 아는 모든 기능에 최적화 된 함수 일 수 있음).
그러나 __getslice__
은 오래 전 사용되지 않았습니다.
문자열에 특정되지 않습니다. 'foo = list (foo)'와 같은 동작을합니다. 또한'str'과'list' 모두'help (* .__ getslice __)'는 명시 적으로 음수 인덱스가 지원되지 않는다고 명시합니다. 'foo [slice (10, -1)]'는 잘 동작합니다. –