设置应该是Python中的列表参数的默认值的最佳做法?

我有一个Python函数,它将一个列表作为参数。 如果我将参数的默认值设置为这样一个空列表:

def func(items=[]): print items 

Pylint会告诉我“危险的默认值[]作为参数”。 所以我想知道这里最好的做法是什么?

使用None作为默认值:

 def func(items=None): if items is None: items = [] print items 

可变默认参数的问题在于它将在函数的所有调用之间共享 – 请参阅Python教程相关部分中的 “重要警告”。

我刚刚第一次遇到这个问题,而我的直接想法是“我不想改变列表,所以我真正想要的是默认为一个不可变列表,所以如果我意外地Python会给我一个错误改变它“。 一个不可变列表只是一个元组。 所以:

   def func(items =()):
      打印项目

当然,如果你把它传递给真正需要列表的东西(例如isinstance(items,list)),那么这会给你带来麻烦。 但无论如何,这是一个代码味道。

对于可变对象作为函数和方法声明中的默认参数,问题是评估和创build发生在同一时刻。 pythonparsing器读取函数头并在同一时刻对其进行求值。

大多数起源者假设每次调用都会创build一个新的对象,但这不正确! 一个对象(在你的例子中是一个列表)在DECLARATION时创build,而不是在你调用方法时按需创build。

对于不可变的对象来说,这不是问题,因为即使所有的调用共享同一个对象,它也是不可变的,因此它的属性保持不变。

作为惯例,您可以使用None对象作为默认值来指示使用默认的初始化,现在可以在函数体中进行默认初始化,这在调用时自然会被计算。

此外,也更好地了解什么是Python,在这里我的小主题片段:

 from functools import wraps def defaultFactories(func): 'wraps function to use factories instead of values for defaults in call' defaults = func.func_defaults @wraps(func) def wrapped(*args,**kwargs): func.func_defaults = tuple(default() for default in defaults) return func(*args,**kwargs) return wrapped def f1(n,b = []): b.append(n) if n == 1: return b else: return f1(n-1) + b @defaultFactories def f2(n,b = list): b.append(n) if n == 1: return b else: return f2(n-1) + b >>> f1(6) [6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1] >>> f2(6) [1, 2, 3, 4, 5, 6]