作为函数的输入传递的python字典在该函数中表现为全局而不是本地

时间:2013-02-25 23:27:28

标签: python variables dictionary global local

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

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.

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

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

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

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

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

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

=============案例4 =============== (由这个问题解释:Global dictionaries don't need keyword global to modify them?

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

4 个答案:

答案 0 :(得分:1)

全局关键字仅用于分配(可能del,我从未尝试过)。对象突变完全有效。

答案 1 :(得分:0)

您已将dict对象传递给函数并在函数内部对其进行了修改,因此当函数返回后它将被修改。不会复制该对象,因此您修改了传递的同一对象,并且在您明确传递对象时,此问题与命名,类似名称,范围等无关。

答案 2 :(得分:0)

当你将一个像整数或字符串这样的基本对象传递给函数时,如果在函数内部更改它,则函数外部的相应对象不会发生任何事情,因为当你使用基本对象时,python会通过值传递它

但是,如果将字典或列表传递给函数,它们将通过引用传递,这意味着您将具有该行为:正如您所见,函数外部的对象已更改。

<强> 编辑: 此外,通过值或通过引用之间存在差异:通过值,&#34;复制&#34;对象的制作是为了在函数中使用;通过引用,完全相同的对象通过引用传递,并且在函数内部对它的修改在外部可见。根据定义,python通过值传递其不可变对象,并通过引用传递其可变对象。

答案 3 :(得分:0)

为了支持@Casey Kuball所说的内容,Python中的每个对象都通过引用传递。每个函数都会收到对您传递的实际对象的引用。修改这些对象取决于它们是否是可变数据类型。

从本质上讲,可以说像dictsetlist这样的可变对象是通过引用传递的。诸如intstrtuple之类的不可变对象按值传递。

您也不应该在某些情况下在函数中覆盖可变对象,从而丢失对传递给该函数的实际对象的引用。

>>> def testfun(b):
...     b = b or {}  # Creates a new object if b is false
...     b['test'] = 2
... 
>>> b = {}
>>> testfun(b)
>>> b
{}