Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么python中的命名参数具有一致的内存?_Python_Reference_Pass By Reference_Default Value - Fatal编程技术网

为什么python中的命名参数具有一致的内存?

为什么python中的命名参数具有一致的内存?,python,reference,pass-by-reference,default-value,Python,Reference,Pass By Reference,Default Value,下面的代码 def f(x,l=[]): for i in range(x): l.append(i*i) print(l) f(2) f(3) 输出 [0,1] [0,1,0,1,4] 而不是琐事 [0,1] [0,1,4] 这意味着命名的参数l实际上是一个单一的一致变量,在新调用f时不会重置该变量 这显然不是一个bug,而是经过设计的 我的问题是,为什么这是理想的行为?对我来说,这似乎更令人困惑而不是有用,这将使我永远不想使用非不变的默认值。函数只定义了

下面的代码

def f(x,l=[]):
    for i in range(x):
        l.append(i*i)
    print(l) 

f(2)
f(3)
输出

[0,1]

[0,1,0,1,4]

而不是琐事

[0,1]

[0,1,4]

这意味着命名的参数
l
实际上是一个单一的一致变量,在新调用
f
时不会重置该变量

这显然不是一个bug,而是经过设计的


我的问题是,为什么这是理想的行为?对我来说,这似乎更令人困惑而不是有用,这将使我永远不想使用非不变的默认值。

函数只定义了一次,所以当使用具有可变类型的默认参数时,它们使用对该默认参数的单一引用(因为它又定义了一次)。这就是为什么在不可变类型(如None、int、str等)上使用list、dict等作为默认参数是不好的做法

例如:


def可变参数(x=[]):
x、 附加(3)
打印(x)
def不可变参数(x=None):
x=x或[]
x、 附加(3)
打印(x)
可变_arg()#打印[3]
可变_arg()#打印[3,3]
不可变_arg()#打印[3]
不可变_arg()#打印[3]

immutable_arg
中,它为每个调用创建一个新的列表,而不是重复使用与
mutable_arg
中相同的默认值,函数只定义一次,因此当使用具有可变类型的默认值时,它们使用对该默认值的单个引用(因为它又定义了一次)。这就是为什么在不可变类型(如None、int、str等)上使用list、dict等作为默认参数是不好的做法

例如:


def可变参数(x=[]):
x、 附加(3)
打印(x)
def不可变参数(x=None):
x=x或[]
x、 附加(3)
打印(x)
可变_arg()#打印[3]
可变_arg()#打印[3,3]
不可变_arg()#打印[3]
不可变_arg()#打印[3]

immutable_arg
中,它为每个调用创建一个新的列表,而不是重复使用与
mutable_arg

中相同的默认值。默认值的计算成本可能比空列表文本要高得多,在这种情况下,在定义函数时,您只需对其求值一次,而不是每次调用函数。另外,在每次调用中都有一种执行代码的方法:将代码放在函数体中。@chepner关于您的第二条注释-显然,将代码放在函数体中会执行每次调用。但是,在命名参数中放入变量真的是创建“静态”变量的pythonic方法吗?@Gulzar将默认参数设置为不可变类型是pythonic的。不过,如果你说的静态就是这个意思的话,它并不强制输入。这就是为什么您可以使用
some_arg=None
并用不同的type@Gulzar创建C风格静态变量的python方法是定义类的方法。但是,仅仅因为可变默认参数没有强大或明显的用例,并不意味着有令人信服的理由不允许它。默认值的计算成本可能比空列表文字要高得多,在这种情况下,在定义函数时,您只需对其求值一次,而不是每次调用函数。另外,在每次调用中都有一种执行代码的方法:将代码放在函数体中。@chepner关于您的第二条注释-显然,将代码放在函数体中会执行每次调用。但是,在命名参数中放入变量真的是创建“静态”变量的pythonic方法吗?@Gulzar将默认参数设置为不可变类型是pythonic的。不过,如果你说的静态就是这个意思的话,它并不强制输入。这就是为什么您可以使用
some_arg=None
并用不同的type@Gulzar创建C风格静态变量的python方法是定义类的方法。但是,仅仅因为可变默认参数没有强有力或明显的用例,并不意味着有令人信服的理由不允许它。我理解发生这种情况的机制。正如问题中所解释的,我也意识到了为什么这是一种不好的做法。然而,我不明白为什么这是设计选择。为什么一开始就允许这个陷阱,而不是自动重新初始化呢?那么请参阅@chepner的评论。为什么每次都要重新定义一个参数?我理解发生这种情况的机制。正如问题中所解释的,我也意识到了为什么这是一种不好的做法。然而,我不明白为什么这是设计选择。为什么一开始就允许这个陷阱,而不是自动重新初始化呢?那么请参阅@chepner的评论。为什么每次都要重新定义参数?