首页 > 解决方案 > 避免默认参数值是可变警告(PyCharm)

问题描述

代码:

def evaluate_fruit(fruits):
    for fruit in fruits:
        if fruit == "Apple":
            print("Good choice!")
        else:
            print("Meh its okay")
    
    
list_o_fruits = ["Apple", "Banana", "Orange"]
    
eval_list = (lambda x=list_o_fruits: evaluate_fruit(x))
    
eval_list()

输出:

Good choice!
Meh its okay
Meh its okay

运行上面的代码时,输​​出符合预期,但是当我将列表/字典(可变)传递给 lambda 函数时,PyCharm 不喜欢它。据我了解,将列表/字典声明为函数的默认值是一种不好的做法,这是有道理的。但是,如果我只阅读列表/字典的内容而不在函数内部以任何方式更改它,那会是可以接受的吗?

无论哪种方式,用列表/字典参数声明我的 lambda 函数的更好方法是什么?网络建议了一种解决方法,通过将默认值设置为“无”,然后使用 if 语句,在“普通”函数中将可变参数作为默认值传递:

def evaluate_fruits(fruits=None):
    if fruits is None:
        fruits = []
    .
    .
    .

我也可以将这个概念用于 lambda 函数,但这会使函数变得冗长且多余,因为我必须为每个生成的 lambda 创建一个 if 语句条件evaluate_fruits()(这有点违背了使用 lambda 的目的)。

举个例子,如果我有五个列表(list_o_fruits1, list_o_fruits2, ..., list_o_fruits5),我想为每个列表( , , ..., )创建eval_list1一个eval_list2lambdaeval_list3函数evaluate_fruits()

我会错过什么吗?

标签: pythonpycharm

解决方案


如果您唯一的要求是将多个元素捆绑到一个对象中,并且该对象不需要是可变的,请使用元组而不是列表。除了修改它们的元素之外,元组提供了列表的所有相同行为。确切地说,可变元素仍然可以被改变,但是元组的元素不能被赋值、添加或删除,并且元组本身被认为是不可变的数据结构。构造元组的语法与列表相同,只是用括号代替方括号:

# Immutable container with immutable elements, perfectly fine to use as a default argument
tuple_o_fruits = ("Apple", "Banana", "Orange")

Python 缺乏通用的可强制执行的 const 正确性是该语言真正让我恼火的少数几件事之一。标准解决方案是使用内置的不可变数据类型tuple代替可变数据类型,如list. 例如 的不可变形式setfrozenset。许多常见的内置类型,例如str,intfloat仅以不可变的形式提供。bytes是一个有趣的例子,因为不可变形式比它的可变替代形式更广为人知bytearray。缺乏不可变替代品的最突出的内置可变类型是dict但不难制作自己的)。

因此,“我如何避免关于可变默认参数的警告”的真正答案是,10 次中有 9 次不使用可变对象,因为不可变的替代方案通常很容易获得。对于您的情况,这应该足够了。


推荐阅读