默认和非默认参数的顺序

时间:2010-11-09 19:43:21

标签: python argument-passing

在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 个答案:

答案 0 :(得分:9)

嗯,range是C代码,它可以做得更好一些。无论如何,你可以这样做:

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

并相应地记录该功能。

答案 1 :(得分: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)

答案 2 :(得分: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 :(得分:1)

如果你真的想要

,你可以自己处理例外
def Range(start=0, end=None):
    if end is None:
        raise AttributeError("end value not specified")
     pass

答案 4 :(得分:1)

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

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

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

答案 5 :(得分:0)

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

todos

例如:

export default (state, action) => {
  switch(action.type) {
    case 'ADD_TODO':
      return {
        ...state,
        todos: [action.payload, ...state.todos]
      }
    case 'DELETE_TODO':
      return {
        ...state,
        todos: state.todos.filter(todo => todo.id !== action.payload)
      }
    case 'UPDATESTATUS_TODO':
      return {
        ...state,
        todos: state.todos.map(todo => {
          if(todo.id === action.payload.id) todo.status = action.payload.intention
          return todo
        })
      }
    default:
      return state
  }
}