Day06 · 数据类型与类型检测

Day06 · 数据类型与类型检测

阶段:阶段一 · 核心基础 | 前置:Day05 | 技术基准:Python 3.15.0

学习目标

  • 认识 Python 的内置数据类型家族:数值型(int/float/complex)、bool、NoneType、bytes
  • 会用 type() 和 isinstance() 检测一个对象的类型
  • 掌握进制表示与互转:bin()、oct()、hex()、int(x, base)
  • 彻底弄清除法三兄弟:/、//、%,以及 divmod()
  • 分清 ==(比值)与 is(比身份),理解小整数缓存与字符串驻留

一、Python 数据类型总览

任何程序都要处理数据,数据就有类型。Python 是动态强类型 语言:变量类型在 = 绑定时才确定,但一旦确定就会严格检查,不会偷偷转换。

Python 内置的基础数据类型(本阶段先认识,后面逐日深入):

大类 类型 例子 是否可变
整型 int 10、-3 不可变
浮点型 float 3.14、1.5e2 不可变
复数 complex 1+2j 不可变
布尔型 bool True、False 不可变
空类型 NoneType None ---
字符串 str "hello" 不可变
字节 bytes b"abc" 不可变
列表 list [1, 2, 3] 可变
元组 tuple (1, 2, 3) 不可变
字典 dict {"k": 1} 可变

二、type() 与 isinstance():检测类型

Python 提供两个内建函数检测对象类型。

2.1、type():返回对象的类型

python 复制代码
# Author: XiaoJia
print(type(10))        # <class 'int'>
print(type(3.14))      # <class 'float'>
print_type = type("hello")
print(print_type)      # <class 'str'>
print(type(True))      # <class 'bool'>
print(type(None))      # <class 'NoneType'>
print(type(1 + 2j))    # <class 'complex'>

版本提示:Python 2 把整数分成 int 和 long 两种;Python 3 中只有一种 int,且支持任意精度 (Python 2 的 long 已合并进 int)。下面这种大整数在 3.15 里直接就能算:

python 复制代码
big = 2 ** 100
print(big)             # 1267650600228229401496703205376
print(type(big))       # <class 'int'>   任意精度,不会溢出

2.2、isinstance():判断是否属于某类型

type() 看"确切类型",isinstance() 看"是不是某类(或其父子类)"。判断继承关系时用 isinstance 更稳妥:

python 复制代码
print(isinstance(10, int))        # True
print(isinstance(3.14, float))    # True
print(isinstance(True, int))       # True   bool 是 int 的子类!
print(isinstance("123", (int, str)))  # True  可传元组,任一匹配即可

注意 bool 是 int 的子类,所以 True == 1、False == 0,True + 1 等于 2(能算,但不推荐在业务里这么用)。

三、数值型细节

3.1、整型 int 与进制表示

Python 整型支持四种进制书写:

进制 前缀 例子 十进制值
二进制 0b / 0B 0b1010 10
八进制 0o / 0O 0o17 15
十进制 无 123 123
十六进制 0x / 0X 0xff 255
python 复制代码
print(0b1010)      # 10   二进制字面量
print(0o17)        # 15   八进制字面量
print(0xff)        # 255  十六进制字面量

版本提示:Python 2 里八进制可以直接写成 017(不带 o),这种写法在 Python 3 中是语法错误(Python 2 遗留,已移除)。Python 3 八进制必须写 0o17。

3.2、进制互转函数

函数 作用
bin(x) 转二进制字符串,带 0b 前缀
oct(x) 转八进制字符串,带 0o 前缀
hex(x) 转十六进制字符串,带 0x 前缀
int(x, base) 把字符串按 base 进制解析成十进制整数
python 复制代码
print(bin(10))       # '0b1010'
print(oct(15))       # '0o17'
print(hex(255))      # '0xff'

# 字符串按指定进制转十进制
print(int("1010", 2))    # 10    二进制字符串 → 十进制
print(int("ff", 16))     # 255   十六进制字符串 → 十进制
print(int("17", 8))      # 15    八进制字符串 → 十进制

3.3、浮点型 float

浮点数有两种写法:小数 3.14、科学计数法 1.5e2(表示 1.5×10²)。

python 复制代码
pi = 3.14159
big = 1.5e2           # 150.0
tiny = 2.5e-3         # 0.0025
print(pi, big, tiny)  # 3.14159 150.0 0.0025
print(type(big))      # <class 'float'>

浮点数还有两个特殊值:float('inf') 无穷大、float('nan') 不是一个数(NaN)。

python 复制代码
print(float('inf'))       # inf   正无穷
print(float('-inf'))      # -inf  负无穷
print(float('nan'))        # nan   非数值

3.4、复数 complex

复数形如 a + bj,虚部用 j(不是数学里的 i,这是电气工程惯例)。

python 复制代码
z = 3 + 4j
print(z.real)            # 3.0   实部
print(z.imag)            # 4.0   虚部
print(z.conjugate())     # (3-4j) 共轭复数
print((1+2j) * (3-4j))   # (11+2j)

四、布尔型与空类型

4.1、bool:只有 True 和 False

布尔值首字母必须大写(True / False),全部小写的 true 是未定义变量。

python 复制代码
print(5 > 3)           # True
print(type(True))      # <class 'bool'>
print(True + False)    # 1   True=1, False=0(能算,但别这么写)

Python 中被判定为"假"(falsy)的值有:False、None、0、0.0、空字符串 ""、空列表 []、空元组 ()、空字典 {} 等;其余基本都算"真"(truthy)。

4.2、NoneType:只有 None

空类型只有一个值 None,表示"什么都没有",常用于函数没有返回值时的默认结果。

python 复制代码
x = None
print(x)               # None
print(type(x))         # <class 'NoneType'>
print(x is None)       # True   判断空值推荐用 is

4.3、bytes 初识

Python 3 严格区分文本(str,Unicode)和二进制(bytes) 。bytes 字面量在前面加 b:

python 复制代码
b = b"abc"
print(b)               # b'abc'
print(type(b))         # <class 'bytes'>

bytes 与 str 之间用 encode() / decode() 转换,编码问题在 Day08 详讲,Day24 文件操作会深入二进制。

五、除法三兄弟:/、//、%

这是新手最容易混的一组运算。

运算符 含义 例子 结果
/ 真除法,结果总是浮点数 7 / 2 3.5
// 整除,向下取整 7 // 2 3
% 取模(余数) 7 % 2 1
python 复制代码
# Author: XiaoJia
a, b = 7, 2
print(a / b)       # 3.5    真除法
print(a // b)      # 3      整除
print(a % b)       # 1      余数
print(a ** b)      # 49     幂运算

版本提示:Python 2 里 / 对两个整数做"整除"(7/2=3);Python 3 改成了"真除法"(7/2=3.5),要整除必须显式写 //。这是 2→3 的经典不兼容点(Python 2 遗留,行为已改)。

注意 // 是向下取整,不是向零取整,所以负数时要当心:

python 复制代码
print(7 // 2)      # 3
print(-7 // 2)     # -4   向下取整(比 -3.5 更小的整数)
print(-7 / 2)      # -3.5

5.1、divmod():一次拿到商和余数

divmod(a, b) 同时返回 (商, 余数):

python 复制代码
q, r = divmod(17, 5)
print(q, r)        # 3 2   等价于 17//5=3, 17%5=2
print(divmod(10, 3))   # (3, 1)

六、== 与 is 的区别

这是面试高频考点,也是新手必踩的坑。

  • ==:比较两个对象的值是否相等。
  • is:比较两个对象是否是同一个对象 (内存地址 id() 是否相同)。
python 复制代码
a = [1, 2, 3]
b = [1, 2, 3]
c = a

print(a == b)      # True   值相等
print(a is b)      # False  不是同一个对象
print(a is c)      # True   c 就是 a,同一对象

可以用 id() 看内存地址佐证:

python 复制代码
print(id(a))       # 例如 2000001
print(id(b))       # 另一个地址
print(id(c))       # 与 a 相同

6.1、小整数缓存与字符串驻留

有两个特殊现象会让你产生"is 有时对有时错"的困惑:

  1. 小整数缓存 :CPython 预先把 -5 ~ 256 的小整数缓存起来复用,所以它们 is 比较常常为真。
  2. 字符串驻留(interning):某些短字符串会被自动复用。
python 复制代码
x = 100
y = 100
print(x is y)       # True   小整数在缓存池里

m = 1000
n = 1000
print(m == n)       # True   值相等
print(m is n)       # 结果取决于运行环境,不要依赖!

小嘉结论:比较值一律用 ==;只有判断"是不是 None / 是不是同一个对象"时才用 is 。判断空值写 x is None,不要写 x == None。永远不要用 is 去比数值或字符串是否相等。

练习题

  1. 用 type() 分别输出 42、3.14、"3.14"、True、None 的类型,并解释为什么 True 既是 bool 又"能当 int 用"。

  2. 把十进制 42 分别转成二进制、八进制、十六进制字符串,再把 "0b1010" 还原成十进制。

  3. 计算 17 / 5、17 // 5、17 % 5、divmod(17, 5),并用一句话说明 // 和 / 在 Python 3 里的区别(对比 Python 2)。

  4. 下面代码打印什么?为什么?

    python 复制代码
    a = "hello"
    b = "hello"
    print(a == b)
    print(a is b)
  5. 写一段代码:定义一个变量 data = None,用 is 判断它是否为 None 并打印提示;再把 data 改成 "ok" 重新判断。

  6. 思考题:为什么说"判断空值应该写 if x is None,而不是 if x == None"?(提示:从 == 可被重载、is 不可被重载两个角度想。)

小结

  • 内置类型家族:int(任意精度)、float、complex、bool、NoneType、str、bytes、list、tuple、dict。
  • 类型检测:type(x) 看确切类型;isinstance(x, 类型) 看归属(bool 是 int 子类)。
  • 进制:0b/0o/0x 前缀书写;bin/oct/hex 转字符串;int("x", base) 按进制解析。
  • Python 3 只有一种 int(无 long);八进制必须 0o;/ 是真除法、// 才是整除。
  • 除法三兄弟:/ 得浮点、// 向下取整、% 取余;divmod(a,b) 一次得商和余数。
  • == 比值,is 比身份(id);小整数缓存与字符串驻留会造成 is 的"假象",比值永远用 ==,判空用 is None。

扩展阅读

相关推荐
叼烟扛炮1 小时前
Linux 学习笔记(二十九):进程信号(上)—— 信号捕捉与异步魔法
linux·运维·笔记·学习·1024程序员节
lingran__1 小时前
Linux进程万字详解(四) | 进程地址空间深度剖析:虚拟内存、页表映射与缺页中断
linux·虚拟地址空间·虚拟内存·1024程序员节·页表·物理内存·缺页中断
多弗朗皮卡丘1 小时前
C++特殊类设计
开发语言·c++·设计模式
紧跟先前的步伐1 小时前
Go AI Agent 实战 18|Tool Calling 的基本原理与完整执行流程
前端·数据库·人工智能·ai·golang·1024程序员节
Wang's Blog1 小时前
Java 项目实战: 交友项目 - 查询单条动态:动态详情页的接口与实现
java·开发语言·交友
yuniko-n1 小时前
【JUC】CAS
java·开发语言
紧跟先前的步伐1 小时前
Go AI Agent 实战 17|模型适配层设计:让模型可替换
开发语言·人工智能·后端·ai·golang
能源探索家2 小时前
本周能源政策密集落子:电力现货规则修订、碳市场扩围至石化化工、储能升格新兴支柱产业
能源·1024程序员节·新型电力系统·十五五规划·能源信息化·能源资讯
女神下凡2 小时前
芯参谋(71):全桥电机驱动电路设计指南
arm开发·stm32·单片机·嵌入式硬件·硬件工程·设计规范·1024程序员节