Реализация функции range в Python
Всем известно про range() в python. Работал с аргументами и задался вопросом: Как в python удается так организовать передачу аргументов в функцию так, что если передать аргументы таким образом: (start, stop), где start и stop некоторые значения, что все передастся нормально, а если таким: (start) то функция range воспримет ее как stop. Можно ли реализовать подобный функционал в python и если да, то как?
Ответы (3 шт):
Это можно сделать с помощью аргументов по умолчанию (default arguments) в функции.
Например, функция range() определена следующим образом:
def range(start, stop=None, step=1):
if stop is None:
stop = start
start = 0
# код функции
Это означает, что если вы передаете только один аргумент в функцию range(), то он будет использован как stop, а start будет равен 0. Если вы передаете два аргумента, то они будут использованы как start и stop соответственно.
Вы можете реализовать подобный функционал в своей функции, используя аргументы по умолчанию и проверку на их значения внутри функции.
Примерно вот так:
def my_range(start, stop=None, step=None):
if stop is None:
stop = start
start = 0
if step is None:
step = 1
index = 0
while True:
tmp = start + index * step
if step > 0 and tmp >= stop:
break
if step < 0 and tmp <= stop:
break
yield tmp
index += 1
for i in my_range(5):
print(i)
print('--------------------')
for i in my_range(2, 5):
print(i)
print('--------------------')
for i in my_range(1, 5, 2):
print(i)
print('--------------------')
for i in my_range(5, 0, -1):
print(i)
CPython имеет открытый исходный код. Упрощённо реализация range выглядит так:
def validate_step(step):
if step is None:
return 1
if step == 0:
raise ValueError('range() arg 3 must not be zero')
return step
def range(*args):
start = stop = step = None
match len(args):
case 3:
step = validate_step(args[2]);
start = args[0]
stop = args[1]
case 2:
start = args[0]
stop = args[1]
step = validate_step(step)
case 1:
stop = args[0]
start = 0
step = 1