--- title: 数据类型 description: Python 的数据类型 keywords: - Python - 数据类型 tags: - FormalSciences/ComputerScience - ProgrammingLanguage/Python - Python/Basics author: 7Wate date: 2023-08-03 --- 在编程领域,理解和掌握各种数据类型是任何编程语言的基础,Python 也不例外。Python 3 提供了多种内置数据类型,包括但不限于数字(整型、浮点型、复数)、布尔型、列表、元组、字符串、集合、字典等,还有函数、模块等高级类型。每种数据类型都有其特定的特性和适用场景。 > 在 Python 中,变量可以被理解为一个标签(tag)或者标记,它是附着在特定对象上的名字。你可以将这个理念理解为在超市里的商品标签,标签告诉你这是什么商品,而商品是具体的物品。同样的,Python 的变量名就像是一个标签,它告诉我们这个变量指向的是什么对象,而对象是存储在内存中的具体数据。 ## 对象与类型 **在 Python 中,几乎所有的数据都可以被视为对象,每一个对象都有其相应的类型。**例如: ```python print(type(123)) # print(type(3.14)) # print(type('hello')) # ``` **Python 是动态类型语言,我们不需要预先声明变量的类型。**在程序运行过程中,变量的类型可以根据赋值而改变。例如: ```python x = 123 # x 是一个整数 print(type(x)) # x = 'hello' # x 变成了一个字符串 print(type(x)) # ``` Python 中有两个内置函数 `id` 和 `type`。 - `id(obj)` 函数:返回对象 `obj` 的唯一标识符,其实质上是该对象在内存中的地址。 - `type(obj)` 函数:返回对象 `obj` 的类型。 ### 引用计数和垃圾收集 Python 不依赖存储期(即对象在内存中存在的时间)来管理变量和对象,而是**使用引用计数。每个对象都会计算有多少个变量引用了它,当引用计数为 0 时,对象就会被垃圾收集器删除**。可以使用内置的 `id` 函数获取对象的标识(这实际上是该对象的内存地址),使用 `type` 函数获取对象的类型。 ```python # 引用计数和垃圾收集的例子: # 在代码中,`sys.getrefcount(a)`可以获得对象`a`的引用计数。 # 当我们创建一个新的引用`b`时,`a`的引用计数增加1。 # 当我们删除`b`时,`a`的引用计数减少1。 import sys a = [] # 创建一个空列表 print(sys.getrefcount(a)) # 输出:2,一个引用来自 a,一个来自 getrefcount 的参数 b = a # 增加一个引用 print(sys.getrefcount(a)) # 输出:3,新增一个引用来自 b b = None # 删除一个引用 print(sys.getrefcount(a)) # 输出:2,b 不再引用 ``` ### 可变类型、不可变类型 Python 中的数据类型可以分为两大类:可变类型与不可变类型。 - **可变类型**:值可以更改,如列表、字典和集合。 - **不可变类型**:值不可更改,如数字、字符串、元组等。 不可变类型的变量如果改变值,实际上是生成了一个新的对象,并使变量引用新的对象。Python 的赋值语句复制的是对象的引用,而不是对象的值。因此,Python 中的“变量”与其他编程语言中的“变量”不完全相同,将其翻译为“引用”可能更加合适。 ```python # 在代码中,`list1`是一个列表,是可变类型。 # 我们可以通过`append`方法修改`list1`,但是`list1`的`id`并未改变,说明`list1`还是同一个对象。 # `x`是一个整数,是不可变类型。当我们改变`x`的值时,`x`的`id`改变了,说明`x`现在是一个新的对象。 # 可变类型:列表 list1 = [1, 2, 3] print(id(list1)) # 输出 list1 的 id list1.append(4) # 修改 list1 print(id(list1)) # id 没有改变 # 不可变类型:整数 x = 1 print(id(x)) # 输出 x 的 id x = x + 1 # 修改 x print(id(x)) # id 改变了 ``` ## Python3 内置类型 Python 3 内置了多种数据类型,同时还内建了许多其他类型,如上下文管理器类型、模块、方法、代码对象、类型对象、内部对象等。 ### 数字类型 数字类型主要用于存储和处理数值。这包括整数、浮点数、复数和布尔类型。 | 类型 | 描述 | 示例 | 可变性 | | ------- | ---------------------------------- | ---------------------- | ------ | | int | 整数,无论大小都可以是正数或负数。 | `123`, `-456`, `0` | 不可变 | | float | 浮点数,包含小数部分的数字。 | `3.14`, `-0.01`, `9.0` | 不可变 | | complex | 复数,包含实部和虚部的数字。 | `1+2j`, `3-4j` | 不可变 | ### 布尔类型 | 类型 | 描述 | 示例 | 可变性 | | ---- | ---------------------- | --------------- | ------ | | bool | 布尔,表示真或假的值。 | `True`, `False` | 不可变 | ### 序列类型 序列类型是一种有序的元素集合,包括字符串、列表和元组。每个元素都有一个相应的索引,可以通过索引来访问。 | 类型 | 描述 | 示例 | 可变性 | | ----- | ---------------------------------------- | -------------------------- | ------ | | str | 字符串,由零个或多个字符组成的文本。 | `'hello'`, `"world"`, `''` | 不可变 | | list | 列表,由一系列按特定顺序排列的元素组成。 | `[1, 'two', 3.0]` | 可变 | | tuple | 元组,类似于列表,但元素不可更改。 | `(1, 'two', 3.0)` | 不可变 | ### 集合类型 集合类型是一个无序的元素集合,其中的元素都是唯一的。这包括集合和冻结集合。 | 类型 | 描述 | 示例 | 可变性 | | --------- | ---------------------------------------- | ---------------------------- | ------ | | set | 集合,一组无序的、不重复的元素。 | `{1, 'two', 3.0}` | 可变 | | frozenset | 不可变集合,类似于集合,但元素不可更改。 | `frozenset({1, 'two', 3.0})` | 不可变 | ### 映射类型 映射类型是一个存储键值对的元素集合,其中的键是唯一的。字典就是一个映射类型。 | 类型 | 描述 | 示例 | 可变性 | | ---- | ---------------------------- | ----------------------------- | ------ | | dict | 字典,包含键值对的数据结构。 | `{'name': 'John', 'age': 25}` | 可变 | ### 特殊类型 | 类型 | 描述 | 示例 | 可变性 | | ------------------ | ------------------------------------------------------ | ------------------- | ------ | | NoneType | 表示 None 的特殊类型。 | `None` | 不可变 | | EllipsisType | 表示省略的特殊类型,主要在切片和 NumPy 库中使用。 | `Ellipsis` 或 `...` | 不可变 | | NotImplementedType | 表示未实现方法的特殊类型,主要在自定义比较方法中使用。 | `NotImplemented` | 不可变 | ### 二进制类型 | 类型 | 描述 | 示例 | 可变性 | | ---------- | ------------------------------------------------------------ | ------------------------- | -------------- | | bytes | 字节,包含零个或多个范围为 0<=x<256 的整数的不可变序列。 | `b'hello'`, `b'\x01\x02'` | 不可变 | | bytearray | 字节数组,包含零个或多个范围为 0<=x<256 的整数的可变序列。 | `bytearray(b'hello')` | 可变 | | memoryview | 内存查看,用于访问其他二进制序列、打包的数组和缓冲区的内部数据。 | `memoryview(b'hello')` | 依据所查看对象 | ### 类、实例和异常 | 类型 | 描述 | 示例 | 可变性 | | --------- | ------------------------ | --------------------------- | ---------- | | object | 对象,所有类的基类。 | `obj = object()` | 依据具体类 | | exception | 异常,程序运行时的错误。 | `raise Exception('Error!')` | 不可变 | ### 其他内置类型 | 类型 | 描述 | 示例 | 可变性 | | --------- | ----------------------------------------------------------- | ------------------------------ | ------ | | function | 函数,包含一系列指令的代码块。 | `def greet(): print('Hello!')` | 不可变 | | type | 类型,表示对象的类型。 | `type(123)` | 不可变 | | generator | 生成器,一种可迭代的对象,由函数定义并使用 `yield` 产生值。 | `(x**2 for x in range(10))` | 不可变 | ## 类型转换 Python 提供了多种函数,用于在不同类型之间进行转换: ```Python x = "123" # 这是一个字符串 print(type(x)) # x = int(x) # 将字符串转为整数 print(type(x)) # x = float(x) # 将整数转为浮点数 print(type(x)) # ``` | 函数 | 描述 | | :-------------------- | :-------------------------------------------------- | | int(x [,base]) | 将 x 转换为一个整数 | | float(x) | 将 x 转换到一个浮点数 | | complex(real [,imag]) | 创建一个复数 | | str(x) | 将对象 x 转换为字符串 | | repr(x) | 将对象 x 转换为表达式字符串 | | eval(str) | 用来计算在字符串中的有效 Python 表达式,并返回一个对象 | | tuple(s) | 将序列 s 转换为一个元组 | | list(s) | 将序列 s 转换为一个列表 | | set(s) | 转换为可变集合 | | dict(d) | 创建一个字典。d 必须是一个 (key, value) 元组序列 | | frozenset(s) | 转换为不可变集合 | | chr(x) | 将一个整数转换为一个字符 | | ord(x) | 将一个字符转换为它的整数值 | | hex(x) | 将一个整数转换为一个十六进制字符串 | | oct(x) | 将一个整数转换为一个八进制字符串 | ## 运算符 在实际开发中,如果搞不清楚运算符的优先级,可以**使用括号来确保运算的执行顺序**。 ```python # 运算符 a = 10 b = 20 print(a + b) # 加法,输出: 30 print(a - b) # 减法,输出: -10 print(a * b) # 乘法,输出: 200 print(a / b) # 除法,输出: 0.5 print(a ** 2) # 幂运算,输出: 100 print(a % 3) # 取模,输出: 1 # 逻辑运算符 print(a > b) # 大于,输出: False print(a < b) # 小于,输出: True print(a == b) # 等于,输出: False print(a != b) # 不等于,输出: True # 成员运算符 s = 'Hello World' print('World' in s) # 输出: True print('Python' not in s) # 输出: True ``` | 运算符 | 描述 | | ------------------------------------------------------------ | ------------------------------ | | `[]` `[:]` | 下标,切片 | | `**` | 指数 | | `~` `+` `-` | 按位取反, 正负号 | | `*` `/` `%` `//` | 乘,除,模,整除 | | `+` `-` | 加,减 | | `>>` `<<` | 右移,左移 | | `&` | 按位与 | | `^` `|` | 按位异或,按位或 | | `<=` `<` `>` `>=` | 小于等于,小于,大于,大于等于 | | `==` `!=` | 等于,不等于 | | `is` `is not` | 身份运算符 | | `in` `not in` | 成员运算符 | | `not` `or` `and` | 逻辑运算符 | | `=` `+=` `-=` `*=` `/=` `%=` `//=` `**=` `&=` `| =``^=``>>=``<<=` | 赋值运算符 |