Skip to content

值与类型:名字绑定了什么 ​

核心概念 ​

Python 中的一切都是对象。数字是对象,字符串是对象,函数也是对象。名字(变量)不存储对象本身,而是绑定到对象的引用。

关键区别:

  • 对象:内存中的实体,有身份(identity)、类型(type)、值(value)
  • 名字:指向对象的标签,可以重新绑定到不同对象
  • 绑定:让名字指向对象的操作(通过 = 赋值)

对象身份与 is 运算符 ​

每个对象都有唯一的身份标识,可以用 id() 函数获取(CPython 中是内存地址):

python
>>> a = 1000
>>> b = 1000
>>> id(a)
140234567890123
>>> id(b)
140234567890456
>>> a is b
False

is 运算符检查两个名字是否绑定到同一个对象(身份相同),而 == 检查值是否相等:

python
>>> a == b
True
>>> a is b
False

a 和 b 的值相等(都是 1000),但它们是内存中的不同对象。

小整数缓存 ​

Python 缓存了小整数对象(通常是 -5 到 256)以提高性能:

python
>>> x = 5
>>> y = 5
>>> x is y
True
>>> id(x) == id(y)
True

这是 CPython 的实现细节,不应依赖它编写逻辑。判断对象身份用 is,判断值相等用 ==。

名字绑定不是赋值 ​

许多语言中,x = 5 表示"把 5 存入变量 x"。Python 中的含义是:

  1. 创建或找到整数对象 5
  2. 让名字 x 绑定到这个对象
python
>>> x = 42
>>> y = x
>>> x = 100
>>> print(y)
42

解释:

  • x = 42:名字 x 绑定到整数对象 42
  • y = x:名字 y 也绑定到同一个整数对象 42
  • x = 100:名字 x 重新绑定到新对象 100
  • y 仍然绑定到原来的对象 42,不受影响

可视化:

text
x = 42      →  [42] ← x
y = x       →  [42] ← x, y
x = 100     →  [42] ← y    [100] ← x

基本类型 ​

整数(int) ​

Python 3 的整数是任意精度的,不会溢出:

python
>>> big = 10 ** 100
>>> print(big)
10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
>>> type(big)
<class 'int'>

浮点数(float) ​

使用 IEEE 754 双精度浮点数,有精度限制:

python
>>> 0.1 + 0.2
0.30000000000000004
>>> 0.1 + 0.2 == 0.3
False

浮点数不能精确表示所有十进制小数。金融计算应使用 decimal.Decimal(后续讲解)。

字符串(str) ​

不可变的 Unicode 文本序列:

python
>>> s = "Hello"
>>> type(s)
<class 'str'>
>>> len(s)
5
>>> s[0]
'H'

字符串用单引号 '...' 或双引号 "..." 包围,语义相同。多行字符串用三引号:

python
>>> text = """This is
... a multi-line
... string"""
>>> print(text)
This is
a multi-line
string

布尔值(bool) ​

只有两个值:True 和 False(注意大写):

python
>>> is_valid = True
>>> type(is_valid)
<class 'bool'>
>>> 5 > 3
True
>>> 5 == 3
False

布尔值是整数的子类:

python
>>> True + True
2
>>> int(True)
1
>>> int(False)
0

None ​

表示"无值"或"空":

python
>>> result = None
>>> type(result)
<class 'NoneType'>
>>> result is None
True

None 是单例对象,整个程序中只有一个 None。检查是否为 None 应使用 is None,不用 == None。

类型检查 ​

使用 type() 获取对象的类型:

python
>>> type(42)
<class 'int'>
>>> type(3.14)
<class 'float'>
>>> type("hello")
<class 'str'>

使用 isinstance() 检查对象是否属于某个类型(或其子类):

python
>>> isinstance(42, int)
True
>>> isinstance(True, int)
True
>>> isinstance(3.14, int)
False
>>> isinstance(3.14, (int, float))  # 检查多个类型
True

isinstance() 比 type() 更灵活,因为它支持继承。

可变 vs 不可变对象 ​

不可变对象:创建后值不能改变。包括 int, float, str, tuple, frozenset。

python
>>> x = "hello"
>>> x[0] = "H"  # 尝试修改字符串
TypeError: 'str' object does not support item assignment

不可变对象的"修改"实际是创建新对象:

python
>>> s = "hello"
>>> s_id = id(s)
>>> s = s + " world"
>>> id(s) == s_id
False

s + " world" 创建了新字符串对象,s 重新绑定到新对象。

可变对象:可以原地修改。包括 list, dict, set。

python
>>> lst = [1, 2, 3]
>>> lst_id = id(lst)
>>> lst.append(4)
>>> lst
[1, 2, 3, 4]
>>> id(lst) == lst_id
True

列表对象的身份没变,但内容变了。

多个名字绑定到可变对象 ​

python
>>> a = [1, 2, 3]
>>> b = a
>>> b.append(4)
>>> print(a)
[1, 2, 3, 4]

a 和 b 绑定到同一个列表对象,通过 b 修改对象会影响 a。这不是复制,而是别名(aliasing)。

要创建独立副本,使用 copy() 或切片:

python
>>> a = [1, 2, 3]
>>> b = a.copy()  # 或 b = a[:]
>>> b.append(4)
>>> print(a)
[1, 2, 3]
>>> print(b)
[1, 2, 3, 4]

动态类型 ​

Python 是动态类型语言:名字可以重新绑定到任何类型的对象:

python
>>> x = 42
>>> type(x)
<class 'int'>
>>> x = "now a string"
>>> type(x)
<class 'str'>

这在静态类型语言中会报错,但 Python 允许。对象有类型,名字没有类型约束(除非使用类型注解,后续章节讲解)。

练习 ​

  1. 身份与相等:预测下列代码的输出,然后实际运行验证:

    python
    a = [1, 2, 3]
    b = [1, 2, 3]
    c = a
    print(a == b)
    print(a is b)
    print(a is c)
  2. 不可变对象:解释为什么以下代码中 y 没有变化:

    python
    x = 10
    y = x
    x = x + 5
    print(y)  # 输出是什么?
  3. 可变对象陷阱:运行以下代码并解释结果:

    python
    list1 = [1, 2, 3]
    list2 = list1
    list2[0] = 999
    print(list1)

    如何修改代码使 list1 不受影响?

  4. 类型检查:编写函数 check_type(obj),打印对象的类型、是否为整数、是否为数字(int 或 float):

    python
    def check_type(obj):
        # 你的代码
        pass
    
    check_type(42)
    check_type(3.14)
    check_type("hello")
  5. 小整数缓存边界:实验确定小整数缓存的上限(提示:从 256 开始尝试)。

完成练习后,打开本章答案页核对。

下一步 ​

理解了对象与名字绑定,下一节学习控制流:如何用 if、while、for 让程序做出决策和重复操作。

回到第一章概览 · 返回Python 学习路线

用心记录每一步成长