作为输入传递给函数的python字典在该函数中充当全局而不是局部 [英] python dictionary passed as an input to a function acts like a global in that function rather than a local

查看:31
本文介绍了作为输入传递给函数的python字典在该函数中充当全局而不是局部的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对以下行为感到非常困惑.案例 1、3 和 4 的表现符合我的预期,但案例 2 则不然.为什么情况 2 允许函数全局更改字典条目的值,即使函数从不返回字典?我使用函数的一个主要原因是将函数中的所有内容与代码的其余部分隔离开来,但是如果我选择在函数内部使用相同的变量名,这似乎是不可能的.我的理解是,在函数中明确定义的任何内容都是该函数的局部变量,但如果字典被定义并作为输入传递给函数,则情况似乎并非如此.>

Python 2.7.2+(默认,2011 年 10 月 4 日,20:06:09)[GCC 4.6.1] 在 linux2输入帮助"、版权"、信用"或许可证"以获取更多信息.

============案例1================

<预><代码>>>>def testfun1(a):... a=2...>>>a=0>>>testfun1(a)>>>一个0

============案例2================

<预><代码>>>>def testfun2(b):... b['test']=2...>>>b={}>>>testfun2(b)>>>乙{'测试':2}

============案例3================

<预><代码>>>>def testfun3():... c=2...>>>c=0>>>testfun3()>>>C0

============案例4================(由这个问题解释:全局字典不需要关键字 global修改它们?)

<预><代码>>>>def testfun4():... d['测试']=10...>>>d={}>>>testfun4()>>>d{'测试':10}

解决方案

Python 的参数评估策略";行为与您可能习惯的语言略有不同.python具有通过共享调用,而不是显式按值调用和按引用调用语义.你本质上总是传递对象本身,对象的可变性决定了它是否可以被修改.列表和字典是可变对象.数字、字符串和元组不是.

您将字典传递给函数,而不是副本.因此,当您修改它时,您也在修改原始副本.

为避免这种情况,您应该在调用函数之前或从函数内部复制字典(将字典传递给 dict 函数应该这样做,即 testfun4(dict(d)) 并将函数定义为 def testfun4(d):).

I am very confused by the behaviour below. Cases 1, 3, and 4 perform as I would expect, but case 2 does not. Why does case 2 allow the function to change the value of the dictionary entry globally, even though the dictionary is never returned by the function? A main reason I am using functions is to isolate everything in the function from the rest of the code, but this does not seem to be possible if I choose to use the same variable names inside of the function. I was under the understanding that anything explicitly defined in a function is local to that function, but this does not seem to be the case if the dictionary is defined and passed as an input to the function.

Python 2.7.2+ (default, Oct  4 2011, 20:06:09) 
[GCC 4.6.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.

=============Case 1===============

>>> def testfun1(a):
...     a=2
... 
>>> a=0
>>> testfun1(a)
>>> a
0

=============Case 2===============

>>> def testfun2(b):
...     b['test']=2
... 
>>> b={}
>>> testfun2(b)
>>> b
{'test': 2}

=============Case 3===============

>>> def testfun3():
...     c=2
... 
>>> c=0
>>> testfun3()
>>> c
0

=============Case 4=============== (explained by this question: Global dictionaries don't need keyword global to modify them?)

>>> def testfun4():
...     d['test']=10
... 
>>> d={}
>>> testfun4()
>>> d
{'test': 10}

解决方案

Python's "parameter evaluation strategy" acts a bit different than the languages you're probably used to. Instead of having explicit call by value and call by reference semantics, python has call by sharing. You are essentially always passing the object itself, and the object's mutability determines whether or not it can be modified. Lists and Dicts are mutable objects. Numbers, Strings, and Tuples are not.

You are passing the dictionary to the function, not a copy. Thus when you modify it, you are also modifying the original copy.

To avoid this, you should first copy the dictionary before calling the function, or from within the function (passing the dictionary to the dict function should do it, i.e. testfun4(dict(d)) and defining the function as def testfun4(d):).

这篇关于作为输入传递给函数的python字典在该函数中充当全局而不是局部的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆