考虑以下代码:
>>> b = 3
>>> def change (b):
... b = 2
...
>>> change(b)
>>> print(b)
3
打印语句返回3这一事实并不让我感到困惑。问题是:这是因为作用域,还是因为函数采用的参数与外部b
无关?
change
内的b
与change
外的b
的作用域不同。在函数的范围内,在传入变量之前调用什么并不重要——目前,它将被称为b
。只要你不从change
返回b
并将其分配给你的"原始"b
,第一个就不会改变。
def change(b):
b = 2
return b
change(b)
print(b) # 3
b = change(b)
print(b) # 2
您正在重新分配b
。它不会更改参数。您可以在分配之前和之后使用id()
函数对此进行测试。
范围答案对于您传递的对象类型是部分正确的。
查看此链接以获取有关python如何"通过值引用"的信息
http://stupidpythonideas.blogspot.com/2013/11/does-python-pass-by-value-or-by.html
下面是另一个链接,它解释了蟒蛇的本地->封闭->全局->内置范围解析,并提供了一些示例:
http://nbviewer.ipython.org/github/rasbt/python_reference/blob/master/not_so_obvious_python_stuff.ipynb#python_legb
FWIW,如果我们考虑可变对象,行为会略有不同:
>>> b = [3]
>>> def change(b):
... b[0] = 2
...
>>> change(b)
>>> print(b)
[2]
>>>
你问了一个相当棘手的问题,因为你在构建问题时使用的术语会让人们给你不同而奇怪的答案。
你有两个选择:
- 我们有范围问题
- 函数内的
b
与函数外的b
无关
好吧,它们都是真的,它们真的只是说同一件事的两种方式。
暂时忘记术语,意识到之间没有任何区别
b = 3
def f(a):
print(a)
f(b)
和
b = 3
def f(b):
print(b)
f(b)
函数签名中的参数名称(函数的def
行)是函数的本地名称,无论函数外部有什么名称。
现在,你可能注意到我回避了函数中的赋值问题。这是因为它很难快速解释,但对于仍处于学习Python早期阶段的人来说,它仍然是可以理解和难忘的(无意冒犯,你似乎是这样)。
以下是一些阅读资料,可以帮助您理解Python中的基本概念:
- http://nedbatchelder.com/text/names.html
- http://www.jeffknupp.com/blog/2013/02/14/drastically-improve-your-python-understanding-pythons-execution-model/
您需要查看全局变量。只需在代码和函数的开头添加global b
,它就会起作用:
>>> global b
>>> b = 3
>>> def change():
... global b
... b = 2
...
>>> b
3
>>> change()
>>> b
2
>>>
您还需要从def change(b)
中删除b
参数,因为这会使b
同时成为local
和global
。您也可以return
b
:
>>> b = 3
>>> def change(b):
... b = 2
... return b
...
>>> b
3
>>> b = change(b)
>>> b
2
这是一个作用域问题。函数中的b是一个局部变量。globals()是一个包含所有全局变量的字典。
b=3
def change (a):
globals()[a] = 2
print b
# 3
change("b")
print b
# 2