#python #python-3.x #oop
#python #функция #значение по умолчанию #аргументы
Вопрос:
Предположим, у меня есть функция python, которая принимает два аргумента, но я хочу, чтобы второй аргумент был необязательным, а значением по умолчанию было то, что было передано в качестве первого аргумента. Итак, я хочу сделать что-то вроде этого:
def myfunc(arg1, arg2=arg1):
print (arg1, arg2)
За исключением того, что это не работает. Единственное обходное решение, о котором я могу подумать, это:
def myfunc(arg1, arg2=None):
if arg2 is None:
arg2 = arg1
print (arg1, arg2)
Есть ли лучший способ сделать это?
Комментарии:
1. Я просто переосмысливаю это, возможно, этого можно достичь с помощью декоратора. На первый взгляд будет неясно, что это делает, так что, вероятно, плохая идея, но это идея.
2. Не непосредственно в строке заголовка функции, нет. Но внутри тела функции, путем тестирования
if argn is None: argn = <default_expression_involving_other_args>
, да.
Ответ №1:
Как говорит @Ignacio, вы не можете этого сделать. В вашем последнем примере может возникнуть ситуация, когда None
является допустимым значением для arg2
. В этом случае вы можете использовать контрольное значение:
sentinel = object()
def myfunc(arg1, arg2=sentinel):
if arg2 is sentinel:
arg2 = arg1
print (arg1, arg2)
myfunc("foo") # Prints 'foo foo'
myfunc("foo", None) # Prints 'foo None'
Комментарии:
1. вероятно, лучше просто установить значение arg2 по умолчанию None и проверить это вместо того, чтобы возиться с пользовательским объектом sentinel, если только вам не нужно обрабатывать предоставленный пользователем параметр, не отличающийся от значения по умолчанию
Ответ №2:
Не совсем. Другие имена аргументов не существуют, пока функция фактически не введена.
Комментарии:
1. Но вы можете немного привести это в порядок, изменив
if
предложение в обходном пути на:arg2 = arg2 or arg1
2. @Michael Это приведет к сбою, если
arg2
является0
,False
или пустой последовательностью.
Ответ №3:
Второй способ, на мой взгляд, хорош: совершенно ясно, что вы делаете, и для всех тех, кто придет после вас и прочитает код. Несмотря на небольшие накладные расходы при документировании поведения по умолчанию, использование ‘None’ или любого другого, чтобы заставить вашу функцию генерировать значение по умолчанию, очень распространено. На мой взгляд, размещение логики внутри вызовов функций, безусловно, не заслуживает похвалы, очень скоро это может стать очень сложным. Поэтому просто оставьте это в теле функции, где находится весь код.