默认参数和非常量参数的顺序
在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)
,但这不是我想讨论的重点。
6 个回答
2
这个功能并不是通过 range
来实现的。你可以使用 *args
或 **args
,然后根据需要处理元组或者字典。例如:
def f(*args): if len(args) == 1: print "assuming the first is default" elif len(args) == 2: print "two arguments were passed" else: print "Complaining"
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)
这样,用户在想要传入除了0以外的值时,可以使用命名的start参数。(虽然命名参数不是必须的,但这样可以让代码更清晰。)
for i in range3(55, start=12)
12
好吧,range
是 C 语言写的代码,它可以做得更好一些。无论如何,你可以这样做:
def range(start, stop=None):
if stop is None: # only one arg, treat stop as start ...
stop = start
start = 0
...
然后相应地对这个函数进行说明。