Python 为什么可以';我不能在函数中使用kwargs来更改变量吗?
Python初学者的问题。我试图改变函数中某些变量的值,但我不明白为什么有时有效,有时无效。所以我想知道幕后发生了什么。如果我写:Python 为什么可以';我不能在函数中使用kwargs来更改变量吗?,python,python-3.x,dictionary,keyword-argument,Python,Python 3.x,Dictionary,Keyword Argument,Python初学者的问题。我试图改变函数中某些变量的值,但我不明白为什么有时有效,有时无效。所以我想知道幕后发生了什么。如果我写: def assign(self, **kwargs): kwargs['test'] = 3 kwargs['steps'] += [1] t = 1 s = [] assign(test=t, steps=s) print(t) print(s) 这还印着呢 1 [] {'test': 1, 'steps': [1, 2, 3]
def assign(self, **kwargs):
kwargs['test'] = 3
kwargs['steps'] += [1]
t = 1
s = []
assign(test=t, steps=s)
print(t)
print(s)
这还印着呢
1
[]
{'test': 1, 'steps': [1, 2, 3]}
现在,如果我将函数赋值为
def assign(self, **kwargs):
kwargs['test'] += 3
kwargs['steps'] += [1, 2, 3]
它更改列表,但不更改整数。所以我想这与整数是不可变的,列表是可变的这一事实有关。所以我想用字典来代替,以确保我的变量被更改。那么:
dict = {'test':1, 'steps': []}
assign(**dict)
print(dict)
静物印刷品
1
[]
{'test': 1, 'steps': [1, 2, 3]}
完全一样的行为,所以现在我真的很困惑。似乎在解包字典时,我不再传递字典变量的引用,因此这些解包的变量是按值复制的?那么,实现我的目标的最佳方式是什么
更新
感谢与@6502的讨论,因为
在Python中,无法更改已传递给函数的参数,因为不能有“指针”或“引用”
最像蟒蛇的方式就是不去做。函数接收参数并提供结果。如果参数是可变的,则可以改变其状态,但不需要更改调用参数本身
然后我决定返回一个包含结果的字典:
def assign(self, **kwargs):
kwargs['test'] += 3
kwargs['steps'] += [1, 2, 3]
return kwargs
dict = {'test':1, 'steps': []}
dict = assign(**dict)
print(dict)
<>这当然是可行的,但是我想知道对大数据的影响,在我看来(来自C++世界),有很多复制。 < p>第一个例子是错误的,你得到<代码> s=(1)< /代码>:
这是因为列表s
是一个参数,steps
,您可以更改此列表的内容。
简单得多:
def assign(step):
step += [1] # change the contents of the list
s = []
assign(step=s)
print(s) # gives [1]
这与关键字参数或dict扩展无关。如果使用**或直接将关键字作为参数,则完全相同
不要试图传递变量«通过引用»。这在python中是不可能的。改为使用返回值
def assign(test, steps):
return 3, steps + [1]
t, s = assign(3, [])
一个简单化语义的方法是考虑所有的Python值都是指向对象的指针,这些指针总是通过值传递。
如果你改变指向调用者的对象,调用者可以看到变异,但是如果你分配变量,你只是在改变它指向的对象,调用者不会注意到
在Python中,无法更改已传递给函数的参数,因为不能有“指针”或“引用”。变异变量的唯一方法是使用其名称
解决方法(在Python 3中)是传递一个可以访问本地的闭包,例如:
def foo(x, y, set_result):
set_result(x + y)
def bar():
res = None
def set_res(x):
nonlocal res
res = x
foo(10, 20, set_res)
print(res)
然而,很少需要这种技巧,因为在具有引用参数传递的语言中,最常见的用途是返回多个值,例如(C++)
其中函数需要返回三个值,x、y和一个成功标志
然而,在Python中,这是不需要的,因为您只需编写
return x, y
并将其用作
x, y = read_xy()
只需将dict直接传递给函数并将其作为常规参数接受即可。是的,我知道这是可行的,但我无法解压缩多个字典。我想了解为什么这个kwargs
不起作用。如果在Python中,由于无法使用“指针”或“引用”,无法更改传递给函数的参数,那么您可能想看看这个问题。模仿这个问题的最具Python风格的方式是什么?@aaragon:最具Python风格的方式是不这样做。函数接收参数并提供结果。如果参数是可变的,则可以改变其状态,但不需要更改调用参数本身。事实上,即使在C++中,通过非const引用传递参数也有某种难闻的气味…至少如果它是一个输出参数,则接受一个显式指针:这样,函数调用方就不会对值的更改感到惊讶。