Порядок аргументов по умолчанию и не по умолчанию
В Python я понимаю, что аргументы по умолчанию выводятся в конце и что аргументы, отличные от значения по умолчанию, не могут следовать аргументу по умолчанию. Это нормально. Как например:
>>> def foo(x=0, y):
return x, y
SyntaxError: non-default argument follows default argument
Это нормально, как ожидалось.
Однако, как насчет того случая, когда я хочу, чтобы первый аргумент был по умолчанию? Как, например, как видно из приведенного выше кода, x
должен быть первым аргументом и должен иметь значение по умолчанию 0.
Можно ли это сделать? Я спрашиваю, потому что даже в функции range
я предполагаю, что это что-то вроде этого:
def range(start=0, end):
pass
Итак, как это делается, и если это невозможно, как это реализовано range
? Обратите внимание, что я настаиваю на том, чтобы первый аргумент был по умолчанию, вот и вся цель. Я использую range
в качестве примера, потому что он идеально подходит для моей проблемы. Конечно, можно было бы реализовать range
как def range(end, start=0)
, но это не так.
Ответы
Ответ 1
Ну, range
- это код C, который может сделать это немного лучше. В любом случае вы можете сделать это:
def range(start, stop=None):
if stop is None: # only one arg, treat stop as start ...
stop = start
start = 0
...
и соответствующим образом документируйте функцию.
Ответ 2
Он не реализован range
. Вы можете использовать *args
или **args
и обрабатывать кортеж или dict, как хотите. Например:
def f (* args): если len (args) == 1: print ", считая, что первый по умолчанию" elif len (args) == 2: print "были переданы два аргумента" еще: распечатать "Жаловаться"
Ответ 3
Есть пара подходов. Первым было бы переключить аргументы в функции, если некоторые из аргументов "None". Это будет работать следующим образом.
def range1(value, end=None):
if end == None:
end = value
value = 0
return _generate_range_values(value, end)
Другим основным методом было бы заставить вашу функцию получить список всех аргументов, которые он получает. Затем он может решить, что делать, исходя из количества аргументов.
def range2(*args):
if len(args) == 1:
start = 0
end = int(args[0])
elif len(args) == 2:
start = int(args[0])
end = int(args[1])
return _generate_range_values(start, end)
Третий способ будет побуждать пользователей передавать именованные аргументы вашей функции, что делает заказ менее важным.
def range3(end, start=0):
return _generate_range_values(start, end)
Затем пользователи назовут его с помощью именованного аргумента start, если они захотят что-то, кроме 0. (Хотя именованный аргумент не требуется, он сохраняет код в явном виде.
for i in range3(55, start=12)
Ответ 4
Вы можете самостоятельно обрабатывать Исключения, если вы действительно этого хотите
def Range(start=0, end=None):
if end is None:
raise AttributeError("end value not specified")
pass
Ответ 5
У меня нет кода для диапазона, но я уверен, что он выполняет этот трюк:
def range(start, stop=None, step=1):
if stop is None:
start, stop = 0, start
...
изменить: Исправлен код на комментарий к Мартино.