我是python的新手,我试图弄清楚如何通过函数传递值。我观察到以下行为
EX1:
def func1():
a = 1
b.add('b')
a = 0
b = set()
func1()
print(a,b)
结果是0 {'b'}
a和b都没有被声明为全局,但是对b的赋值改变了b的全局值,是因为b是可变变量吗?
EX2:
def func1():
b.add('b')
def func2():
b = set()
func1()
func2()
print(b)
Traceback (most recent call last):
File "test_variables.py", line 10, in <module>
func2()
File "test_variables.py", line 8, in func2
func1()
File "test_variables.py", line 4, in func1
b.add('b')
NameError: name 'b' is not defined
为什么在这种情况下,b不能在func1()中分配?
EX3:
我必须将变量从函数传递给函数
def func1(b):
b.add('b')
def func2():
b = set()
func1(b)
print(b)
func2()
这次打印{'b'}
EX4:
我还可以做的是在外面定义b
def func1():
b.add('b')
def func2():
func1()
print(b)
b = set()
func2()
它也打印{'b'}
提前感谢您的帮助
答案 0 :(得分:0)
当你将一个可变变量传递给你通过引用传递的函数时,这意味着你要创建另一个变量(它只存在于函数的范围内),它指向同一个对象。
此外,Python以您可以使用的方式工作,并查看您在外部范围内的变量(这就是ex1
中您可以添加内容的原因
在 EX1 中,func1()
知道a
和b
,但无法为其分配值(除非您在函数内部将它们定义为global
!)。当您执行a = 1
时,python只会创建一个新的a
变量,该变量仅存在于该函数内。
b.add('b')
是可能的,因为你指的是set
对象(这是不可变的)。如果您尝试在函数内部使用b = 'b'
之类的内容,请再次创建一个本地b
变量,并保持外部集不受影响。
答案 1 :(得分:0)
以下是基于Python Language Reference "Naming and Binding"文档中给出的解释的简化答案。
让我们看看你的第一个例子:
def func1():
a = 1
b.add('b')
在此示例中,您执行两项单独的操作。
首先,您将值1
和绑定取值为a
。此绑定在包含其执行的范围内发生 :在这种情况下,范围是函数func1
。
其次,您查找与名称b
相关联的值,并在该值上调用方法add
。由于这是一个查找,而不是绑定,它不仅限于立即封闭范围,而是会找到包含该名称的最近的封闭范围。在这种情况下,由于函数func1
的范围不包含名称b
,因此将检查下一个封闭范围:这是全局范围, 包含名称b
,这就是使用的值。
答案 2 :(得分:0)
你的问题叫做范围。范围是在哪里定义的通用名称。所以当你声明一个变量时:
b = 0
任何处于相同范围或更低范围的东西都可以看到它的定义。
b = 1
def func():
print(b)
func()
这是有效的,因为b已经在该范围内定义,在这种情况下,b是全局的(一切都可以看到它的定义)。
def func():
b = 0
def func1():
print(b)
func()
func1()
这不起作用,因为b现在是一个局部变量,它只在func()中定义,而不是func1()
b = 1
def func():
b = 0
def func1():
print(b)
func()
func1()
这将打印0,因为b是在全局级别定义的。将全局变量设置为新值,无论您在何处执行此操作,都将始终使该新值全局可用
但你也必须考虑订购。
print(b)
b = 1
不起作用
b = 1
print(b)
b = 0
将打印b = 1,因为在打印之前该值未设置为0
答案 3 :(得分:0)