我有一个Python函数,它接受一个列表作为参数。如果我将参数的默认值设置为空列表,像这样:
def func(items=[]):
print items
Pylint会提示我"危险的默认值[]作为参数"。所以我想知道这里的最佳实践是什么?
我有一个Python函数,它接受一个列表作为参数。如果我将参数的默认值设置为空列表,像这样:
def func(items=[]):
print items
Pylint会提示我"危险的默认值[]作为参数"。所以我想知道这里的最佳实践是什么?
使用None
作为默认值:
def func(items=None):
if items is None:
items = []
print items
func(items=new([]))
的语法。 - ninjageckoitems
是一个可迭代类型,我通常会写成 items = items or []
。 - Neil G我第一次遇到这个问题,我的第一反应是“好吧,我根本不想改变列表,所以我真正想要的是默认为一个不可变列表,这样如果我不小心更改它,Python会给我报错。”不可变列表就是元组。所以:
def func(items=()): print items
当然,如果你将它传递给确实需要列表的某些东西(例如 isinstance(items, list)),那么这可能会让你陷入麻烦。但是这本身就是一种代码异味。
my_copy = list(items)
。你针对一个常见问题提出了简单而巧妙的解决方案。 - Mark RansomNone
对象来表示使用默认初始化,现在可以在函数体中执行,自然会在调用时进行评估。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]
def func(items=())
。元组是不可变的,因此pylint会保持安静,但问题要求列表,因此这并不总是相关或可能的。 - Ant