Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何更改函数中变量的范围?python_Python_Function_Scope - Fatal编程技术网

如何更改函数中变量的范围?python

如何更改函数中变量的范围?python,python,function,scope,Python,Function,Scope,这似乎是一个非常愚蠢的问题,但我对Python中的作用域规则感到困惑。在下面的示例中,我将两个带有值的变量(x,y)发送到一个函数,该函数应该更改它们的值。当我打印结果时,变量没有改变 def func1(x,y): x=200 y=300 x=2 y=3 func1(x,y) print x,y #prints 2,3 现在,如果这是C++,我会通过引用(&)将它们发送给该函数,从而能够改变它们的值。那么Python中的等价物是什么?更重要的是,当您将对象发送到函数时,

这似乎是一个非常愚蠢的问题,但我对Python中的作用域规则感到困惑。在下面的示例中,我将两个带有值的变量(x,y)发送到一个函数,该函数应该更改它们的值。当我打印结果时,变量没有改变

def func1(x,y):
    x=200
    y=300

x=2
y=3

func1(x,y)

print x,y #prints 2,3

现在,如果这是C++,我会通过引用(&)将它们发送给该函数,从而能够改变它们的值。那么Python中的等价物是什么?更重要的是,当您将对象发送到函数时,实际会发生什么?Python是否对这些对象进行了新的引用?

将它们视为函数的一部分。当函数结束时,它的所有变量也会消失

x=2
y=3

def func(x,y):
    x=200
    y=300

func(x,y) #inside this function, x=200 and y=300
#but by this line the function is over and those new values are discarded
print(x,y) #so this is looking at the outer scope again
如果您想让函数完全按照您编写的方式修改值,可以使用
全局
,但这是非常糟糕的做法

def func(x,y):
    global x #these tell the function to look at the outer scope 
    global y #and use those references to x and y, not the inner scope
    x=200
    y=300

func(x,y)
print(x,y) #prints 200 300
这样做的问题是,在最好的情况下,调试会成为一场噩梦,而在最坏的情况下,调试完全不可能。这类事情在函数中通常被称为“副作用”——设置一个不需要设置的值,并且在不显式返回它的情况下这样做是一件坏事。通常,您应该编写的修改项目的唯一函数是对象方法(例如
[].append()
修改列表,因为返回新列表是愚蠢的!)

这样做的正确方法是使用返回值。试试像这样的东西

def func(x,y):
    x = x+200 #this can be written x += 200
    y = y+300 #as above: y += 300
    return (x,y) #returns a tuple (x,y)

x = 2
y = 3
func(x,y) # returns (202, 303)
print(x,y) #prints 2 3
为什么不起作用?因为你从来没有告诉程序对元组做任何事情,只是为了计算它。让我们现在分配它

#func as defined above

x=2 ; y=3
x,y = func(x,y) #this unpacks the tuple (202,303) into two values and x and y
print(x,y) #prints 202 303

此外,.所有Python名称都是对对象的引用。函数参数仅绑定到传入的对象。没有内存位置,在表达式中使用名称时总是取消引用名称。赋值是重新绑定,而不是更改原始内存位置。因此,
x=200
正在创建一个新对象(
int(200)
),并在
x
中存储对该对象的引用。内部作用域具有从外部作用域访问变量的隐式权限,但需要从外部作用域修改变量的显式权限。这是我所能说的最简洁的。(CPython可能会选择在这里重用现有的
int()
对象,但这是一个实现细节)。因此,尽管
x
y
内部
func1
开始绑定到相同的
int()
对象作为模块作用域中的全局
x
y
名称,通过在函数内部分配给它们,您只能恢复本地名称。全局名称仍然引用其原始值。如何使用函数更改x,y?在函数末尾显式地
返回x,y
,然后调用
x,y=func(x,y)
@Reboot\u 87:您不能;您传入的对象是不可变的,因此不可能更改它们,并且不能仅根据传入的内容在外部范围中重新绑定名称。(您可以使用
global
关键字全局地重新绑定名称
x
y
,但无论传入什么对象,都会发生这种情况;在这种情况下,func(a,b)只是修改x和y…我现在明白了。Thanks@Reboot_87我用不同的方法做了一个相当大的编辑。尝试所有方法。如果可能的话,不要使用
global
——这是一个糟糕的实践,让调试变得非常困难。