Странные аргументы диапазона

Функция диапазона в python3 принимает три аргумента, две из которых являются необязательными. Итак, список аргументов выглядит так:

[start], stop, [step]

поэтому это означает (исправьте меня, если я ошибаюсь) есть необязательный аргумент перед необязательным аргументом. Но если я попытаюсь определить такую ​​функцию, я получаю следующее:

>>> def foo(a = 1, b, c = 2):
    print(a, b, c)
SyntaxError: non-default argument follows default argument

- это то, что я не могу сделать как "нормальный" пользователь python, или могу как-то определить такую ​​функцию? Конечно, я мог бы сделать что-то вроде

def foo(a, b = None, c = 2):
    if not b:
        b = a
        a = 1

но, например, функция справки затем покажет странную информацию. Поэтому я действительно хочу знать, возможно ли это определить функцию, описанную выше (первая).

Ответ 1

range() принимает 1 позиционный аргумент и два необязательных аргумента и интерпретирует эти аргументы по-разному в зависимости от того, сколько аргументов вы передали.

Если был передан только один аргумент, предполагается, что он является аргументом stop, в противном случае первый аргумент интерпретируется как стартовый.

В действительности, range(), закодированный в C, принимает переменное количество аргументов. Вы можете подражать этому так:

def foo(*params):
    if 3 < len(params) < 1:
        raise ValueError('foo takes 1 - 3 arguments')
    elif len(params) == 1
        b = params[0]
    elif:
        a, b = params[:2]
    c = params[2] if len(params) > 2 else 1

но вы также можете просто поменять аргументы:

def range(start, stop=None, step=1):
    if stop is None:
        start, stop = 0, start

Ответ 2

range не принимает аргументы ключевого слова:

range(start=0,stop=10)
TypeError: range() takes no keyword arguments

требуется 1, 2 или 3 позиционных аргумента, они оцениваются по их числу:

range(stop)              # 1 argument
range(start, stop)       # 2 arguments
range(start, stop, step) # 3 arguments

то есть. невозможно создать диапазон с определенными stop и step и по умолчанию start.

Ответ 3

def foo(first, second=None, third=1):
     if second is None:
         start, stop, step = 0, first, 1
     else:
         start, stop, step = first, second, third