对象

对象是 Python 中对数据的抽象。Python 程序中的所有数据都是由对象或对象间关系来表示的。

例如计算 x + y 就有对象 xy+ 其实是调用了 __add__ 方法对象。

[1,2] + [3,4]
[1, 2, 3, 4]
list.__add__
<slot wrapper '__add__' of 'list' objects>
[1,2].__add__([3,4])
[1, 2, 3, 4]

每个对象都有各自的编号、类型和值。一个对象被创建后,它的编号就绝不会改变,可以将其理解为该对象在内存中的地址。

id([1,2]), type([1,2]) # 实例对象 [1,2] 的编号 和 类型
(2229938322504, list)
id(list), type(list) # 类对象 list 的编号 和 类型
(140736641645872, type)

对象的值在 Python 中是一个相当抽象的概念:

  • 对象的值并没有一个规范的访问方法;
  • 对象的值并不要求具有特定的构建方式,例如由其全部数据属性组成等;
  • 比较运算符实现了一个特定的对象的值概念,可以认为正是通过实现对象比较,间接地定义了对象的值。
# 列表对象 [1,2] 和类对象 list 
# 是两个不同对象,值是不相等的
[1,2] == list 
False

具有固定值的对象为不可变对象,例如数字,字符串,元组(包含的对象集不可变),相等的两个值,可能会也可能不会指向同一个对象,看具体实现。

# 元组的对象集固定不可变
t = ([1,2],(3,4))
print(id(t[0]),id(t[1]),t)
del t[0][:]
print(id(t[0]),id(t[1]),t)
2229937078536 2229937013960 ([1, 2], (3, 4))
2229937078536 2229937013960 ([], (3, 4))
# 同一个对象 1
print(id(1))
print(id(1))
140736642126656
140736642126656
# 两个不同对象 1000
print(id(1000))
print(id(1000))
2229938479344
2229938479248

对象的编号保持不变,可以改变值的对象为可变对象。对于可变对象,分别创建两个相等的值,一定是不同对象。

# 可变对象 a,值改变了还是 a
a = [1,2]
print(id(a), a)
del a[:]
print(id(a), a)
2229937082056 [1, 2]
2229937082056 []
# 类对象 A,增加属性 a 还是 A
class A:pass
print(id(A), A)
A.a = 0
print(id(A), A)
2229917928424 <class '__main__.A'>
2229917928424 <class '__main__.A'>
a = []
b = []
print(id(a))
print(id(b))
a == b
2229937416840
2229937416648


True

类或函数对象的哈希值基于其 id,创建两个看起来完全一样的类或函数,id 是不一样的,而可哈希对象必须具有相同的哈希值,比较结果才会相同。

def f():pass
print(id(f))
a = f

def f():pass
print(id(f))
b = f
a == b
2229938263992
2229938264128


False