Python对象类型
我一直在学习python,我有一个疑问,我不确定我的想法是否正确。正如您所知,Python是一种OOP语言,所有对象都有一个id、类型和值。 然而,有一个概念,我不确定我是否理解得很好。它是可变和不可变的对象。 我知道有些对象是可变的,比如数组、列表,还有一些对象是不可变的,比如字符串、整数、元组等等。 基本上,主要的区别是不可变的不能改变它的值。例如,如果我有一个int变量:Python对象类型,python,object,python-3.x,mutable,Python,Object,Python 3.x,Mutable,我一直在学习python,我有一个疑问,我不确定我的想法是否正确。正如您所知,Python是一种OOP语言,所有对象都有一个id、类型和值。 然而,有一个概念,我不确定我是否理解得很好。它是可变和不可变的对象。 我知道有些对象是可变的,比如数组、列表,还有一些对象是不可变的,比如字符串、整数、元组等等。 基本上,主要的区别是不可变的不能改变它的值。例如,如果我有一个int变量: x=1 它的价值总是一样的 在那行代码之后,如果我创建了另一个var x,但现在=2,这是另一个对象,因为它们有不同的
x=1
它的价值总是一样的
在那行代码之后,如果我创建了另一个var x,但现在=2,这是另一个对象,因为它们有不同的id,对吗?但是现在,我如何通过id访问var,例如我的第一个xvar
希望你能帮忙。
谢谢!:) 这似乎更像是关于范围的问题,。。为此,我建议您阅读本文 假设我们有以下内容
x = 1
def PrintStuff(x):
print (x)
PrintStuff(2)
>>> 2
在函数PrintStuff
中,x
是一个局部变量
函数PrintStuff
的外部有一个global变量x
def PrintStuff(x):
print( locals()["x"])
PrintStuff(2)
>>> 2
要获取全局x
,有多个选项,但是现在让我们使用globals()
函数,它返回一个包含所有全局变量的字典
x = 1
def PrintStuff(x):
print( x)
print( globals()["x"])
PrintStuff(2)
>>> 2
>>> 1
类似地,我们可以使用locals()
函数来获取本地x
def PrintStuff(x):
print( locals()["x"])
PrintStuff(2)
>>> 2
但是现在,我如何通过id访问var,例如我的第一个xvar
你不能。当您这样做时:
x = 1
x = 2
当python执行x=2
时,您分配给x
的1
对象没有任何可以访问它的引用,因此您无法以任何方式访问它。没有一种东西能让你根据它的id
访问任何对象,比如get\u object\u from\u id
当一个对象没有任何引用时,它实际上是不可访问的。当垃圾收集器运行时,对象将被销毁(实际上,在CPython中,大多数对象都会立即销毁,但无法保证对象何时销毁)
正如Martijn所指出的,对象的id
只是一个实现细节,当对象被破坏时,解释器可能会重用它,因此,即使从理论角度来看,像get\u object\u from\u id
这样的函数也无法以任何合理的方式实现
此外,赋值与可变类型和不可变类型无关。
在对可变类型和不可变类型执行操作时,可以看到它们之间的差异。例如:
some_list.append(1)
>>> a = (1, 2)
>>> b = (1, 2)
>>> a is b # is compare the ids just like: id(a) == id(b)
False
>>> a[0] is b[0]
True
将1
添加到某些列表
(修改它),而不创建新的列表对象,同时:
a = 1
a += 2
此处,a
不会通过将其值增加到3
来修改,而是将值为3
的新整数对象指定给a
您可以使用id
检查a
s是否为不同的对象:
>>> a = 1
>>> id(a)
25889896
>>> a += 2
>>> id(a)
25889848
请注意,依赖id
是一个非常糟糕的选择。例如:
some_list.append(1)
>>> a = (1, 2)
>>> b = (1, 2)
>>> a is b # is compare the ids just like: id(a) == id(b)
False
>>> a[0] is b[0]
True
正如您所见,解释器决定对两个不同的元组重复使用相同的对象1
。这是一个用于小整数的优化,因为整数是不可变的
一句话:
id
只能告诉你在某一时刻两件事情是否不一样。任何其他用法都是错误的。Python对象的id
是一个内部实现细节,不用于标识值。例如,当值被垃圾收集时,ID被重新使用。不要挂断他们;最好将它们用作调试辅助工具,以确定两个对象确实(不)相同。如果将新对象绑定到x
,则绑定到它的旧对象将立即被垃圾回收(在cpython中)。它一去不复返了。