16

在 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以此为例,因为它非常适合我的问题。当然可以实现rangeas def range(end, start=0),但这不是重点。

4

6 回答 6

11

那么,rangeC 代码是否可以做得更好。无论如何,你可以这样做:

def range(start, stop=None):
    if stop is None: # only one arg, treat stop as start ...
        stop = start
        start = 0
    ...

并相应地记录功能。

于 2010-11-09T19:50:35.620 回答
3

有几种方法。第一个是切换函数中的参数,如果某些参数是“无”。那会像这样工作。

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)

然后,当用户想要 0 以外的值时,用户将使用命名的 start 参数调用它。(虽然不需要命名参数,但它使代码保持清晰。

for i in range3(55, start=12)
于 2010-11-09T19:54:44.180 回答
2

它不是由range. 您可以根据需要使用*args**args处理元组或字典。例如:

定义 f(*args):
  如果 len(args) == 1:
     print "假设第一个是默认的"
  elif len(args) == 2:
     print "通过了两个参数"
  别的:
     打印“投诉”

于 2010-11-09T19:50:39.957 回答
1

如果你真的想要,你可以自己处理异常

def Range(start=0, end=None):
    if end is None:
        raise AttributeError("end value not specified")
     pass
于 2010-11-09T19:50:24.107 回答
1

我没有范围的代码,但我确信它会执行这种技巧:

def range(start, stop=None, step=1):
    if stop is None:
        start, stop = 0, start
    ...

编辑:根据 martineau 的评论更正了代码。

于 2010-11-09T19:55:05.973 回答
0

对于具有第一个默认值参数后跟其他参数的函数:

def fn(first=value, *rest):
    # code

例如:

def fn(first=1, *rest):
    print(first)

fn()
fn(11, 2, 3)
>>>
1
11
于 2020-12-14T01:55:15.200 回答