Почему некоторые функции Python имеют дополнительный набор круглых скобок вокруг списка аргументов?

Я видел некоторые функции Python, написанные следующим образом:

def get_year((year,prefix,index,suffix)):
  return year

Как это отличается (если вообще) от других функций без дополнительных круглых скобок, таких как:

def do_format(yr,pfx,id,sfx):
  return "%s %s %s/%s"%(yr, id, pfx, sfx)

Или это просто вопрос вкуса в стилях или если они отличаются друг от друга, может ли get_year() быть переписанным в стиле do_format() или наоборот без эффекта существующего синтаксиса вызывающего абонента?

Ответ 1

Функция get_year в вашем примере использует автоматически распакованный параметр tuple (это функция, удаленная с Python 3). Чтобы вызвать его, вы даете ему один параметр, и ожидается, что этот параметр будет состоять из четырех значений.

# Invocation
my_input = [2013, 'a', 'b', 'c'] # sequence does NOT have to be a tuple!
my_year = get_year(my_input) # returns 2013

Переписать это для Python 3, но не изменить вызов (другими словами, не нарушать существующий код, который вызывает get_year):

def get_year(input_sequence):
    year, prefix, index, suffix = input_sequence
    return year

Это, по сути, означает, что распаковка автоматически выполняется автоматически. В этом конкретном случае вы можете просто написать

def get_year(input_sequence):
    return input_sequence[0]

Для получения дополнительной информации прочитайте PEP 3113.

Ответ 2

Первая функция принимает один аргумент кортежа, тогда как вторая функция принимает 4 аргумента. Вы можете передать эти параметры по отдельности или в виде кортежа с оператором splat, который распакует кортеж в отдельные параметры.

например:

# Valid Invocations
print do_format(*('2001', '234', '12', '123'))  # Tuple Unpacking
print do_format('2001', '234', '12', '123')     # Separate Parameter
print get_year(('2001', '234', '12', '123'))

# Invalid invocation. 
print do_format(('2001', '234', '12', '123'))   # Passes tuple

Ответ 3

Все они эквивалентны (вызывающему не нужно будет изменять):

# 2.x unpacks tuple as part of the function call, 3.x raises exception
def get_year((year,prefix,index,suffix)):
    """get year from (year, prefix, index, suffix) tuple"""
    return year

# 2.x and 3.x, you unpack tuple in the function call
def get_year(year_tuple):
    """get year from (year, prefix, index, suffix) tuple"""
    year, prefix, index, suffix = year_tuple
    return year

# 2.x and 3.x, speedier because you don't unpack what you don't need
def get_year(year_tuple):
    """get year from (year, prefix, index, suffix) tuple"""
    return year_tuple[0]