Создание экземпляра класса range

В Python имеется класс range, который генерирует последовательность из чисел. При его вызове можно указать один, два или три параметра. Но я не могу понять, как именно это работает? Почему я могу указать (stop) или (start, stop) в параметрах?

Если бы start был необязательным параметром (start = 0), то stop не мог бы находится позади него, так как обязательные параметры указывается первыми. Так же в Python'е нет перегрузки конструкторов. Из кода единственное, что я смог узнать: ничего:

    def __init__(self, stop): # real signature unknown; restored from __doc__
        pass

Так вот, мне интересно, можно ли сделать что-то подобное или это реализуется только на уровне исходного кода Python?


Ответы (2 шт):

Автор решения: Кирилл Малышев

Это делается примерно так

def __init__(self, start, end=None, step=1):
    if end is None:
        self.start = 0
        self.end = start
    else:
        self.start = start
        self.end = end
    self.step = step
→ Ссылка
Автор решения: Alex Buryat

Для 3.10 лучше использовать паттерн match/case:

@staticmethod
def validate_step(value):
    if value is None:
        return 1
    if value == 0:
        raise ValueError('step value not been zero')
    
@staticmethod
def validate_start_and_end(start, stop):
    if start < stop:
        return start, stop
    else:
        raise ValueError('start value mast been less then stop')
    
def __init__(self, *args):
    match len(args):
        case 3:
            self.step = self.validate_step(args[2])
            self.start, self.stop = self.validate_start_and_end(args[0], args[1])
        case 2:
            self.start, self.stop = self.validate_start_and_end(args[0], args[1])
            self.step = 1.0
        case 1:
            self.step = 1.0
            self.start = 0.0
            self.stop = float(args[0])
        case _:
            raise TypeError(f"range expected 1, 2 or 3 argument, got {len(args)}")
→ Ссылка