Да, вы можете передавать объекты любого типа slice
.Документация не упоминает об ограничениях для типа аргументов среза, а исходный код для конструктора среза говорит только о том, что «start, stop и step являются объектами python».
list(range(20))[slice(10.0)]
отклоняет объект слайса с аргументами с плавающей точкой, но это, похоже, относится к типу списка.Сама модель данных не выполняет неявную проверку типов перед вызовом __getitem__
.Вы можете написать свой собственный класс, который принимает больше нетрадиционных срезов.Пример:
>>> class Fred:
... def __getitem__(self, idx):
... return "baz"
...
>>> x = Fred()
>>> print(x[slice("Foo", "Bar")])
baz
>>> print(x[1.0: -10.5])
baz
Что касается того, есть ли практическая практическая причина разрешить нецелые срезы, ни один не приходит на ум ... Но у сообщества Python есть культурная норма "мы"все взрослые здесь ".То есть что-то не должно быть запрещено только потому, что для этого нет очевидного практического применения.Если кто-то хочет сделать что-то, что кажется глупым, то при прочих равных условиях мы должны позволить ему.
Мы установили, что определяемые пользователем типы могут принимать любые виды фрагментов, которые они хотят.Но что, если вы хотите иметь возможность нарезать встроенные типы необычными срезами?Вы не можете изменить реализацию типа списка, чтобы удалить проверку типа, которую он делает.__index__
пригодится как способ определения новых типов, которые можно использовать для нарезки списков.Например,
>>> class Begin:
... def __index__(self):
... return 0
...
>>> class End:
... def __index__(self):
... return -1
...
>>> list(range(20))[slice(Begin(), End())]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]