【问题标题】:Why do some Python functions have an extra set of parenthesis around the argument list?为什么一些 Python 函数在参数列表周围有一组额外的括号?
【发布时间】:2013-02-14 17:17:48
【问题描述】:

我见过一些这样写的 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() 的样式,反之亦然,而不影响现有调用者的语法?

【问题讨论】:

  • 元组拆包,ole待机。
  • 请注意,幸运的是,此功能在 Python 3 中已消失。

标签: python arguments parentheses


【解决方案1】:

第一个函数接受一个元组参数,而第二个函数接受 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

【讨论】:

  • 如何重写元组解包函数以不使用该功能?
  • @WilliamKF。我不明白。什么特点?如果您不想进行元组解包,则只需将它们作为元组传递,就像在第一个函数中一样。
  • @WilliamKF 要以do_format 的形式编写get_year,只需删除这些括号。就是这样。
  • 上面有人写道,元组打包在 Python v3 中已经消失了,那么你将如何重写函数以便调用者不必更改但它可以在 Python v3 中工作?
  • @WilliamKF。首先,您对哪个使用元组解包感到困惑。这是使用它的第二个功能。在您编辑的问题中,您正在谈论更改第一个函数,即使在 Python 3 中也可以。现在,就更改第二个函数而言,而不影响调用者调用它的方式,这是不可能的。因为元组解包是由于参数传递方式的一些变化而完成的。因此,您的调用者不应使用 splat 运算符在第二个函数中解包,而应像第二个示例中那样将它们作为单独的参数传递。
【解决方案2】:

您示例中的 get_year 函数使用自动解包的元组参数(这是 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

【讨论】:

  • +1 完美。现在我得到了OP的实际要求。看来我自己也糊涂了。 :(对不起OP。
  • 到目前为止,我只在 Python 2.7 上工作。但现在我认为,是时候转向 Python 3.x 了。 :)
【解决方案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]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-24
    • 2016-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-13
    相关资源
    最近更新 更多