Python 变量 (variables)、对象 (objects) 和引用 (references)
Python 变量 {variables}、对象 {objects} 和引用 {references}
- 1. Object Reference in Python (Python 对象引用)
- 1.1. Object Identities in Python (Python 对象标识号)
- 1.2. sys.getrefcount() in Python (Python 引用计数)
- 2. Mutable Objects and Immutable Objects in Python (Python 可变对象和不可变对象)
- 2.1. Mutable Objects in Python (Python 可变对象)
- 2.2. Immutable Objects in Python (Python 不可变对象)
- References
Data model
https://docs.python.org/3/reference/datamodel.html
Objects are Python’s abstraction for data. All data in a Python program is represented by objects or by relations between objects.
对象是 Python 对数据的抽象。Python 程序中的所有数据都是由对象或对象间关系来表示的。
Every object has an identity, a type and a value. An object’s identity never changes once it has been created; you may think of it as the object’s address in memory. The is
operator compares the identity of two objects; the id()
function returns an integer representing its identity.
每个对象都有相应的标识号、类型和值。 一个对象被创建后它的标识号就绝不会改变;你可以将其理解为该对象在内存中的地址。is
运算符比较两个对象的标识号是否相同;id()
函数返回一个代表其标识号的整数。
For CPython, id(x)
is the memory address where x
is stored.
在 CPython 中,id(x)
就是存放 x
的内存的地址。
Object (a.k.a. value): a “thing”. Lists, dictionaries, strings, numbers, tuples, functions, and modules are all objects. “Object” defies definition because everything is an object in Python.
对象无法定义,因为在 Python 中一切都是对象。
Variable (a.k.a. name): a name used to refer to an object.
Pointer (a.k.a. reference): describes where an object lives (often shown visually as an arrow)
Equality: whether two objects represent the same data
Identity: whether two pointers refer to the same object
- Variables in Python (Python 变量)
在 Python 中,变量存放对象的引用 (或者说是对象的地址)。因此每个变量所需要的存储空间大小一致,与所指向对象的类型无关,因为每个变量都只是保存了对象的地址。
在 Python 中,变量是对对象的引用,变量用来指向任意的对象。Python 变量更像是指针,而不是数据存储区域。
变量是对对象的引用,变量没有类型,变量可以指向任何对象。变量是分配在栈 (stack) 上,用来指向某一个对象。
- Objects in Python (Python 对象)
在 Python 中,对象是分配的一块内存,有足够的空间去表示它们所代表的值,支持特定类型的相关操作。
在 Python 中,对象存储在堆 (heap) 内存中,对象通过调用 __new__
创建。
在 Python 中,对象分配在内存空间上,用来存放真正的数据。对象有类型,不同对象有不同的类型。不同对象根据存储的数据大小不同,所占用的内存空间也不同。
在 Python 中,一切皆对象,完全地面向对象。对象是一个抽象,可想象成现实中的一个实际物体。
- References in Python (Python 引用)
在 Python 中,引用建立了变量和对象之间的关系,即某个变量指向了某个对象 (或者说指向某个内存空间),二者之间的关系便是引用。在 Python 中,赋值 (=
) 操作时,从变量到对象自动建立的连接关系,称为引用。
因为变量是无类型的,它可以指向任何对象。同一个对象可能被多个变量引用 (指向),因此会涉及一个对象引用计数,以及引用同一个对象的不同变量之间的操作影响。
message = "hello world"
:
- 创建一个变量
message
,变量message
保存对象的地址。 - 创建一个对象 (字符串类型对象),并开辟一块存储空间,对象的
id
是0x020
,type
是str
,存储的value
是"hello world"
。 - 将变量和对象,通过指针或引用链接起来。语句
message = "hello world"
是引用,表明该变量指向该对象。
1. Object Reference in Python (Python 对象引用)
Python variables hold references to objects, not the actual objects themselves.
Reassigning a variable does not affect other variables referencing the same object unless explicitly updated.
在 Python 中,变量是对对象的引用。当你将一个值赋值给变量时,实际上是在创建一个指向表示该值的对象的引用。
x = 5
x = 5
When x = 5
is executed, Python creates an object to represent the value 5 and makes x
reference this object.
y = x
y = x
Python encounters the first statement, it creates an object for the value 5 and makes x reference it. The second statement creates y
and references the same object as x
, not x
itself. This is called a Shared Reference, where multiple variables reference the same object.
encounter /ɪnˈkaʊntə(r)/
vt. 遭遇;遇到 (尤指令人不快或困难的事);与...邂逅;偶然碰到;意外地遇见
n. 遭遇;(意外、突然或暴力的) 相遇;邂逅;冲突;(体育) 比赛;交锋
x = "Geeks"
x = "Geeks"
Python creates a new object for the value "Geeks"
and makes x
reference this new object. The variable y
remains unchanged, still referencing the original object 5.
geek /ɡiːk/
n. 怪胎;不善交际的人;(某一领域的) 高手、极客
y = "Computer"
y = "Computer"
Python creates yet another object for "Computer"
and updates y
to reference it. The original object 5 no longer has any references and becomes eligible for garbage collection.
eligible /ˈelɪdʒəbl/
adj. 有资格的;合格的;(指认为可做夫妻的男女) 合意的,合适的,中意的;具备条件的
n. 合格者;称心如意的人;合适者;合乎条件的人或东西
1.1. Object Identities in Python (Python 对象标识号)
Python id()
function returns the "dentity"
of the object. The identity of an object is an integer, which is guaranteed to be unique and constant for this object during its lifetime. Two objects with non-overlapping lifetimes may have the same id()
value. In CPython implementation, this is the address of the object in memory.
在 Python 中,变量是对象的引用,而不是装有对象的容器。对象具有三要素:标识号 (identity)、类型 (type)、值 (value)。
标识号 (identity) 用于唯一标识对象,通常对应对象在计算机内存中的地址。使用内置函数 id(obj)
返回对象唯一标识号。
For immutable types, operations that compute new values may actually return a reference to any existing object with the same type and value, while for mutable objects this is not allowed. For example, after a = 1; b = 1
, a
and b
may or may not refer to the same object with the value one, depending on the implementation. This is because int is an immutable type, so the reference to 1 can be reused. This behaviour depends on the implementation used, so should not be relied upon, but is something to be aware of when making use of object identity tests.
对于不可变类型,计算新值的操作实际上可能返回一个指向具有相同类型和值的任何现存对象的引用,而对于可变对象来说这是不允许的。例如在 a = 1; b = 1
之后,a
和 b
可能会也可能不会指向同一个值为一的对象。这是因为 int
是不可变对象,因此对 1 的引用可以被重用。此行为依赖于所使用的具体实现,因此不应该依赖它,而在使用对象标识测试时需要注意。
However, after c = []; d = []
, c
and d
are guaranteed to refer to two different, unique, newly created empty lists. (Note that e = f = []
assigns the same object to both e
and f
.)
不过,在 c = []; d = []
之后,c
和 d
保证会指向两个不同的、独特的、新创建的空列表。(注意 e = f = []
会将同一个对象同时赋值给 e
和 f
。)
#!/usr/bin/env python
# coding=utf-8m = 1
print(f"m: {m}, id(m): {id(m)}")n = 3
print(f"n: {n}, id(n): {id(n)}")k = 1
print(f"k: {k}, id(k): {id(k)}")
/home/yongqiang/miniconda3/bin/python /home/yongqiang/stable_diffusion_work/stable_diffusion_diffusers/yongqiang.py
m: 1, id(m): 8885000
n: 3, id(n): 8885064
k: 1, id(k): 8885000Process finished with exit code 0
m
和 k
开始指向同一个对象,重新赋值之后,m
和 n
指向同一个对象。赋值 (=
) 操作就是对象标识号 (identity
) 的传递,可以理解为内存地址的传递,变量一旦使用完毕,可被清理。
#!/usr/bin/env python
# coding=utf-8m = 1
print(f"m: {m}, id(m): {id(m)}")n = 3
print(f"n: {n}, id(n): {id(n)}")k = 1
print(f"k: {k}, id(k): {id(k)}")m = 3
print(f"\nm: {m}, id(m): {id(m)}")
print(f"n: {n}, id(n): {id(n)}")
/home/yongqiang/miniconda3/bin/python /home/yongqiang/stable_diffusion_work/stable_diffusion_diffusers/yongqiang.py
m: 1, id(m): 8885000
n: 3, id(n): 8885064
k: 1, id(k): 8885000m: 3, id(m): 8885064
n: 3, id(n): 8885064Process finished with exit code 0
Caching can work only with immutable objects, notice that integer, string, tuples are immutable. As we thought, dict objects are returning different id() value and there seems no caching here.
#!/usr/bin/env python
# coding=utf-8dic1 = {"A": 1, "B": 2}
dic2 = {"A": 1, "B": 2}print(f"dic1: {dic1}, id(dic1): {id(dic1)}")
print(f"dic2: {dic2}, id(dic2): {id(dic2)}")
/home/yongqiang/miniconda3/bin/python /home/yongqiang/stable_diffusion_work/stable_diffusion_diffusers/yongqiang.py
dic1: {'A': 1, 'B': 2}, id(dic1): 131096553812096
dic2: {'A': 1, 'B': 2}, id(dic2): 131096548228352Process finished with exit code 0
对象中含有标准的头部信息:类型标识符。标识对象类型,表示对象存储的数据的类型。类型 (type
) 可以限制对象的取值范围和可执行的操作。使用内置函数 type(obj)
返回对象所属类型。
值 (value
) 表示对象存储的数据的信息,使用内置函数 print(obj)
可以直接打印值。
#!/usr/bin/env python
# coding=utf-8mutable_list = [1, 3, 5, 7]print(f"mutable_list: {mutable_list}, id(mutable_list): {id(mutable_list)}")print(f"mutable_list[0]: {mutable_list[0]}, id(mutable_list[0]): {id(mutable_list[0])}")
print(f"mutable_list[1]: {mutable_list[1]}, id(mutable_list[1]): {id(mutable_list[1])}")
print(f"mutable_list[2]: {mutable_list[2]}, id(mutable_list[2]): {id(mutable_list[2])}")
print(f"mutable_list[3]: {mutable_list[3]}, id(mutable_list[3]): {id(mutable_list[3])}")
/home/yongqiang/miniconda3/bin/python /home/yongqiang/stable_diffusion_work/stable_diffusion_diffusers/yongqiang.py
mutable_list: [1, 3, 5, 7], id(mutable_list): 139477622141952
mutable_list[0]: 1, id(mutable_list[0]): 8885000
mutable_list[1]: 3, id(mutable_list[1]): 8885064
mutable_list[2]: 5, id(mutable_list[2]): 8885128
mutable_list[3]: 7, id(mutable_list[3]): 8885192Process finished with exit code 0
1.2. sys.getrefcount() in Python (Python 引用计数)
The Python sys.getrefcount()
method returns the reference count for an object. The reference count indicates the number of references points to the object in memory.
在 Python 中,变量是对对象的引用。当你将一个值赋值给变量时,实际上是在创建一个指向表示该值的对象的引用。
#!/usr/bin/env python
# coding=utf-8m = [1, 3, 5, 7]
n = m
n.append(9)print(f"m: {m}")
print("n:", n)
/home/yongqiang/miniconda3/bin/python /home/yongqiang/stable_diffusion_work/stable_diffusion_diffusers/yongqiang.py
m: [1, 3, 5, 7, 9]
n: [1, 3, 5, 7, 9]Process finished with exit code 0
m
和 n
都引用了同一个列表对象。当我们通过 n
引用修改列表,添加 9 时,这一变化会同时反映在 m
和 n
中。
#!/usr/bin/env python
# coding=utf-8import sysm = "yong"
print(f"m: {m}, id(m): {id(m)}, refcount: {sys.getrefcount(m)}")n = "qiang"
print(f"n: {n}, id(n): {id(n)}, refcount: {sys.getrefcount(n)}")k = m
print(f"\nk: {k}, id(k): {id(k)}, refcount: {sys.getrefcount(k)}")
print(f"m: {m}, id(m): {id(m)}, refcount: {sys.getrefcount(m)}")
/home/yongqiang/miniconda3/bin/python /home/yongqiang/stable_diffusion_work/stable_diffusion_diffusers/yongqiang.py
m: yong, id(m): 123627565429104, refcount: 5
n: qiang, id(n): 123627563516784, refcount: 5k: yong, id(k): 123627565429104, refcount: 6
m: yong, id(m): 123627565429104, refcount: 6Process finished with exit code 0
2. Mutable Objects and Immutable Objects in Python (Python 可变对象和不可变对象)
The value of some objects can change. Objects whose value can change are said to be mutable; objects whose value is unchangeable once they are created are called immutable. (The value of an immutable container object that contains a reference to a mutable object can change when the latter’s value is changed; however the container is still considered immutable, because the collection of objects it contains cannot be changed. So, immutability is not strictly the same as having an unchangeable value, it is more subtle.) An object’s mutability is determined by its type; for instance, numbers, strings and tuples are immutable, while dictionaries and lists are mutable.
值可以改变的对象被称为可变对象;值不可以改变的对象就被称为不可变对象。(一个不可变容器对象如果包含对可变对象的引用,当后者的值改变时,前者的值也会改变;但是该容器仍属于不可变对象,因为它所包含的对象集是不会改变的。因此,不可变并不严格等同于值不能改变,实际含义要更微妙。) 一个对象的可变性是由其类型决定的;例如,数字、字符串和元组是不可变的,而字典和列表是可变的。
Python 中有两种类型的对象:可变对象 (mutable objects) 和不可变对象 (immutable objects)。
-
可变对象在创建后可以被修改。列表 (list)、字典 (dictionary)、集合 (set) 等是可变对象。
-
不可变对象在创建后不能被修改。整数 (integer)、浮点数 (float)、字符串 (string)、元组 (tuple) 等是不可变对象。
在 Python 中,变量是对对象的引用。当你将一个值赋值给变量时,实际上是在创建一个指向表示该值的对象的引用。
2.1. Mutable Objects in Python (Python 可变对象)
#!/usr/bin/env python
# coding=utf-8mutable_list = [1, 3, 5, 7]
another_mutable_list = mutable_listanother_mutable_list.append(9)print("mutable_list:", mutable_list)
print(f"another_mutable_list: {another_mutable_list}")
/home/yongqiang/miniconda3/bin/python /home/yongqiang/stable_diffusion_work/stable_diffusion_diffusers/yongqiang.py
mutable_list: [1, 3, 5, 7, 9]
another_mutable_list: [1, 3, 5, 7, 9]Process finished with exit code 0
2.2. Immutable Objects in Python (Python 不可变对象)
#!/usr/bin/env python
# coding=utf-8immutable_string = "yongqiang"
another_immutable_string = immutable_stringprint("immutable_string:", immutable_string)
print(f"another_immutable_string: {another_immutable_string}")another_immutable_string = another_immutable_string.upper()print("\nimmutable_string:", immutable_string)
print(f"another_immutable_string: {another_immutable_string}")
/home/yongqiang/miniconda3/bin/python /home/yongqiang/stable_diffusion_work/stable_diffusion_diffusers/yongqiang.py
immutable_string: yongqiang
another_immutable_string: yongqiangimmutable_string: yongqiang
another_immutable_string: YONGQIANGProcess finished with exit code 0
- TypeError: ‘str’ object does not support item assignment
#!/usr/bin/env python
# coding=utf-8immutable_string = "yongqiang"
another_immutable_string = immutable_stringprint("immutable_string:", immutable_string)
print(f"another_immutable_string: {another_immutable_string}")immutable_string[0] = 'a'
/home/yongqiang/miniconda3/bin/python /home/yongqiang/stable_diffusion_work/stable_diffusion_diffusers/yongqiang.py
immutable_string: yongqiang
another_immutable_string: yongqiang
Traceback (most recent call last):File "/home/yongqiang/stable_diffusion_work/stable_diffusion_diffusers/yongqiang.py", line 10, in <module>immutable_string[0] = 'a'~~~~~~~~~~~~~~~~^^^
TypeError: 'str' object does not support item assignmentProcess finished with exit code 1
References
[1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/