Я думаю, что вопрос основан на неправильной посылке:
Я понимаю, что тот факт, что он реализован в C, вероятно, допускает поведение, которое было бы нарушением в Pythonland.
Он реализован в C, но поведение не является нарушением в «Pythonland». Подпись в документации просто некорректна (на самом деле она неверна, это приблизительная «реальная подпись» - это легко понять).
Например , даже не поддерживает именованные параметры, но в соответствии с документацией он должен:>>> range(stop=10) TypeError: range() does not take keyword arguments
class range(object):
def __init__(self, *args):
start, step = 0, 1
if len(args) == 1:
stop = args[0]
elif len(args) == 2:
start, stop = args
elif len(args) == 3:
start, stop, step = args
Таким образом, реализация более соответствует следующим:
range
Это действительный Python и (грубо) делает то, что range(*args)
внутренне ( фактическая реализация (CPython, Python 3.6.1) может быть немного иной, поэтому серьезно не относиться к этому классу).
Однако подобная подпись, *args
вероятно, не очень полезна для пользователей (особенно новых пользователей, которые даже не знают, что range
означает). Имея документацию, которая говорит, range
имеет 2 подписи: range(stop)
и range(start, stop[, step])
может быть (технически) точной, но она «объясняет», как интерпретируется подпись.
Что касается причин : у меня нет никаких надежных источников, но я быстро отсканировал свой код:
Я использую range(stop)
гораздо чаще, чем range(start, stop)
или range(start, stop, step)
. Таким образом, случай с одним аргументом был, вероятно, особенным и достаточно распространенным, чтобы иметь удобство для него. Было бы очень неприятно всегда писать range(0, stop)
повсюду.