python中怎么设置默认值_在Python中设置应该是列表的参数
的默认值的最佳实践?...
我有⼀个将列表作为参数的python函数。如果我将参数的默认值设置为如下空列表:
def func(items=[]):
print items
⽪林特会告诉我"危险的默认值[]作为参数"。所以我想知道这⾥的最佳实践是什么?
这是每⼀个Python新⼿都会碰上⼀两次的东西,⽪林特阻⽌你写⼀个可怕的⾍⼦真是太酷了!python新手代码错了应该怎么改
使⽤None作为默认值:
def func(items=None):
if items is None:
items = []
print items
可变默认参数的问题在于,它将在函数的所有调⽤之间共享——请参见Python教程的相关部分中的"重要警告"。
啊,哇,我很惊讶⼈们知道这件事。=)我⾮常讨厌python的这个特性,以⾄于我编写了⾃⼰的decorator库来⽀持func(items=new([]))语法。
谢谢!看起来Python认为没有⼀个是与列表完全不同的类型,所以我想知道Python是否可以将⼀个参数的默认值设置为⼀个不同的类型(⽐如没有)(我知道Python是⼀个没有类型的语⾔,但是我来⾃C++…LOL)?
它与C++之类的强类型语⾔⾮常不同。只要把变量想象成引⽤对象的名称,所有的东西都是通过引⽤传递的。
@WIM:我认为您的意思是"静态的",⽽不是强烈的;Python是强类型但动态类型的。
谢谢,维姆!然后,当您使⽤⼀个变量时,如何确定它是⼀个实际的列表还是仍然保持其默认值"⽆"?或者你在使⽤前总是要检查⼀下?
你不必每次都检查它,只有当你期望它不会是你认为应该的。这就像在C++中检查指针/引⽤是否为空。你不会每次都检查它,但在许多情况下,防范它确实是有意义的。
如果我希望items是⼀个不可重写的类型,我通常会写items = items or []。
我第⼀次遇到这个问题,我的第⼀个想法是"好吧,反正我不想改变列表,所以我真正想要的是默认为不可变列表,这样如果我不⼩⼼改变了它,python就会给我⼀个错误。"不可变列表只是⼀个元组。所以:
def func(items=()):
print items
当然,如果你把它传递给某个真正想要列表的东西(⽐如isinstance(items,list)),那么这会给你带来⿇烦。但⽆论如何,这是⼀种代码味道。
如果在函数内部需要复制,请使⽤my_copy = list(items)。你想出了⼀个简单⽽巧妙的解决⼀个常见问题的⽅法。
对于可变对象作为函数和⽅法声明中的默认参数,问题在于,计算和创建发⽣在完全相同的时刻。python解析器读取函数头并同时对其进⾏评估。
⼤多数⼈都认为每次调⽤都会创建⼀个新对象,但这不正确!声明时创建⼀个对象(在⽰例中是⼀个列表),调⽤⽅法时不按需创建。
对于不成问题的可修改对象,因为即使所有调⽤共享同⼀对象,它也是可修改的,因此它的属性保持不变。
作为⼀种惯例,您将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]
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论