如何在 Python 中制作 "local object"?
How to make a "local object" in Python?
我想知道为什么 Python 在以下情况下表现不同?
案例 1. 我更改了局部整型变量,但全局变量保持不变。嗯,没关系。
N = 1
def Func1(x):
x = 0
Func1(N)
print(N) # prints 1
案例 2。我更改了 属性 局部对象...似乎我已经更改了全局对象。
class C1:
def __init__(self):
self.A = 1
Obj1 = C1()
def Func2(x):
x.A = 0 #here is a confusing moment
Func2(Obj1)
print(Obj1.A) #prints 0
也许我对对象是否真的是本地的理解不完整?在那种情况下,我如何编写类似于 "local object"?
的代码?
在python中,函数的参数是通过赋值传递的。 [1]
在 python 中,对象不会在赋值时被复制。
因此,在您的第二个示例中,要制作对象的 本地副本 ,您必须显式复制它,例如使用 copy.deepcopy(x)
[2]
因此您的第二个代码将变为:
import copy
class C1:
def __init__(self):
self.A = 1
Obj1 = C1()
def Func2(x):
x = copy.deepcopy(x) # Make a local copy of the object
x.A = 0 #No more confusion
Func2(Obj1)
print(Obj1.A) #prints 1
您将苹果与橙子进行比较(或您想要说的任何内容)。在您的第一种情况下,您试图更改函数内部全局变量的值。当您调用函数时,您的全局变量没有改变,因为 Python 通过赋值而不是引用来传递变量 。观察第一种情况下我们通过赋值时会发生什么:
>>> N = 1
>>> def foo(x):
x = 0
return x
>>> foo(N) # this will not change N. we need to pass N by assingment
0
>>> N
1
>>> N = foo(N) # this will change N
>>> N
0
>>>
此行为记录在 Python3 FAQ:
Remember that arguments are passed by assignment in Python. Since assignment just creates references to objects, there’s no alias between an argument name in the caller and callee, and so no call-by-reference per se.
重点是我的。
在第二种情况下,您没有更改全局变量的值。 Obj1
是对象而不是变量。 您更改了 Obj1
的属性,而不是 Obj1
本身 。看看当我们尝试通过引用传递 Obj1
时会发生什么:
>>> class CL:
def __init__(self):
self.A = 1
>>> Obj1 = CL()
>>> def foo(x):
# lets try chaning the actual value that Obj1 holds
x = None
>>> foo(Obj1) # did it change?
>>> Obj1
<__main__.CL object at 0x03B29B50>
>>> # Nope
我想知道为什么 Python 在以下情况下表现不同?
案例 1. 我更改了局部整型变量,但全局变量保持不变。嗯,没关系。
N = 1
def Func1(x):
x = 0
Func1(N)
print(N) # prints 1
案例 2。我更改了 属性 局部对象...似乎我已经更改了全局对象。
class C1:
def __init__(self):
self.A = 1
Obj1 = C1()
def Func2(x):
x.A = 0 #here is a confusing moment
Func2(Obj1)
print(Obj1.A) #prints 0
也许我对对象是否真的是本地的理解不完整?在那种情况下,我如何编写类似于 "local object"?
的代码?在python中,函数的参数是通过赋值传递的。 [1]
在 python 中,对象不会在赋值时被复制。
因此,在您的第二个示例中,要制作对象的 本地副本 ,您必须显式复制它,例如使用 copy.deepcopy(x)
[2]
因此您的第二个代码将变为:
import copy
class C1:
def __init__(self):
self.A = 1
Obj1 = C1()
def Func2(x):
x = copy.deepcopy(x) # Make a local copy of the object
x.A = 0 #No more confusion
Func2(Obj1)
print(Obj1.A) #prints 1
您将苹果与橙子进行比较(或您想要说的任何内容)。在您的第一种情况下,您试图更改函数内部全局变量的值。当您调用函数时,您的全局变量没有改变,因为 Python 通过赋值而不是引用来传递变量 。观察第一种情况下我们通过赋值时会发生什么:
>>> N = 1
>>> def foo(x):
x = 0
return x
>>> foo(N) # this will not change N. we need to pass N by assingment
0
>>> N
1
>>> N = foo(N) # this will change N
>>> N
0
>>>
此行为记录在 Python3 FAQ:
Remember that arguments are passed by assignment in Python. Since assignment just creates references to objects, there’s no alias between an argument name in the caller and callee, and so no call-by-reference per se.
重点是我的。
在第二种情况下,您没有更改全局变量的值。 Obj1
是对象而不是变量。 您更改了 Obj1
的属性,而不是 Obj1
本身 。看看当我们尝试通过引用传递 Obj1
时会发生什么:
>>> class CL:
def __init__(self):
self.A = 1
>>> Obj1 = CL()
>>> def foo(x):
# lets try chaning the actual value that Obj1 holds
x = None
>>> foo(Obj1) # did it change?
>>> Obj1
<__main__.CL object at 0x03B29B50>
>>> # Nope