由kwargs传递给函数的变量不会被更新。
由kwargs传递给函数的变量不会被更新。
这个问题已经有了答案:
在某些语言中,您可以使用特殊保留字(如 ref 或 val)按引用或按值传递参数。当您将参数传递给 Python 函数时,它不会在函数结束时更改参数的值。唯一的方法是使用 global 保留字(或者目前我所理解的是这样)。
示例1:
k = 2 def foo (n): n = n * n #clarity regarding comment below square = n return square j = foo(k) print j print k
会显示:
>>4 >>2
显示 k 的值未改变。
在此示例中,变量 n 从未更改。
示例2:
n = 0 def foo(): global n n = n * n return n
在此示例中,变量 n 被更改了。
在 Python 中是否有一种方法可以调用函数并告诉 Python 该参数是值参数还是引用参数,而不是使用 global?
在Python中,您不能在函数内更改不可变对象,如str
或tuple
,但您可以执行以下操作:
def foo(y): y[0] = y[0]**2 x = [5] foo(x) print x[0] # prints 25
然而,这是一种奇怪的方法,除非您需要始终将某些元素平方,否则不建议使用。
请注意,在Python中,您还可以返回多个值,使得某些按引用传递的用例变得不那么重要:
def foo(x, y): return x**2, y**2 a = 2 b = 3 a, b = foo(a, b) # a == 4; b == 9
当您以此方式返回值时,它们作为元组返回,然后将其拆开。
编辑:
另一种思考这个问题的方式是,虽然您不能在Python中显式地按引用传递变量,但您可以修改传入的对象的属性。在我的示例(和其他示例)中,您可以修改传入的列表的成员。但是,您将无法完全重新指定传入的变量。例如,请查看以下两个代码片段,它们看起来可能做了类似的事情,但最终结果不同:
def clear_a(x): x = [] def clear_b(x): while x: x.pop() z = [1,2,3] clear_a(z) # z will not be changed clear_b(z) # z will be emptied
本质上有三种“函数调用”:
- 按值传递
- 按引用传递
- 按对象引用传递
Python是一种“按对象引用传递”的编程语言。
首先,了解变量和变量值(对象)是两件不同的事很重要。变量“指向”对象。变量不是对象。再次强调:
变量不是对象
例如,在以下代码行中:
>>> x = []
[]
是空列表,x
是指向空列表的变量,但x
本身不是空列表。
将变量(在上面的示例中为x
)视为一个盒子,将“变量的值”([]
)视为盒子内的对象。
按对象引用传递(Python中的情况):
在此,“对象引用通过值传递”。
def append_one(li): li.append(1) x = [0] append_one(x) print x
此处,语句x = [0]
创建一个指向对象[0]
的变量x
(盒子)。
在调用函数时,将创建一个新的盒子li
。 li
的内容与盒子x
的内容相同。 两个盒子都包含相同的对象。也就是说,这两个变量都指向内存中的同一个对象。因此,对由li
指向的对象进行的任何更改也将反映在由x
指向的对象上。
总之,上述程序的输出将是:
[0, 1]
注意:
如果在函数中重新分配变量li
,那么li
将指向内存中的一个单独对象。 然而,x
将继续指向它早先所指向的相同对象。
例如:
def append_one(li): li = [0, 1] x = [0] append_one(x) print x
程序的输出将是:
[0]
按引用传递:
来自调用函数的盒子被传递到被调用的函数中。隐式地,盒子的内容(变量的值)被传递给被调用的函数。因此,在被调用的函数中更改盒子的内容将反映在调用的函数中。
按值传递:
在被调用的函数中创建了一个新的盒子,并将来自调用函数的盒子的内容的副本存储到新的盒子中。