导航菜单

  • 1.VSCode开发
  • 2.什么是Python?
  • 3.请详细解释Python代码的执行过程
  • 4.请详细解释解释型语言与编译型语言的主要区别
  • 5.你知道哪些Python的编码规范?
  • 6.数据类型
  • 7.Python中如何声明多个变量并赋值
  • 8.Python有哪些内置数据结构
  • 9.!=和is not运算符有什么区别?
  • 10.进制
  • 11.编码
  • 12.print
  • 13.Python中break、continue、pass有什么作用?
  • 14.namedtuple有什么作用?
  • 15.Python的range函数如何运用?
  • 16.Python中join()和split()函数有什么区别?
  • 17.Python中如何将字符串转换为小写?
  • 18.Python中如何删除字符串中的前置空格?
  • 19.Python中如何使用索引反转字符串
  • 20.什么是Python的成员运算符?
  • 21.请详细说明Python中逻辑运算符(`and`、`or`、`not`)
  • 22.什么是Python的关系运算符?
  • 23.什么是Python的赋值和算术运算符?请详细说明赋值运算符、算术运算符的种类、使用方法、优先级规则。
  • 24.请详细解释Python中整数除法、取模运算和幂运算三个运算符。
  • 25.如何在Python中表示和转换不同进制的数字
  • 26.什么是Python的位运算符?
  • 27.请详细说明Python中三元表达式(Ternary Expression)的工作原理
  • 28.Python中如何实现switch语句?
  • 29.什么是Python的负索引?
  • 30.Python中如何实现字符串替换操作?
  • 31.Python中append、insert和extend有什么区别?
  • 32.请详细说明Python中`enumerate()`函数的作用
  • 33.Python中remove、del和pop有什么区别?
  • 34.Python中如何更改列表元素的数据类型?
  • 35.请详细说明Python中列表(list)和元组(tuple)的区别
  • 36.什么是Python元组的解封装?
  • 37.详细说明Python字典
  • 38.Python中KeyError、TypeError和ValueError有什么区别?
  • 39.请详细解释Python中`read()`、`readline()`和`readlines()`三种文件读取方法
  • 40.Python中iterable、iterator和generator的区别与联系
  • 41.Python中如何读取大文件?
  • 42.请详细解释Python中浅拷贝(shallow copy)和深拷贝(deep copy)的区别
  • 43.什么是Python的Lambda函数?
  • 44.Python中的reduce函数有什么作用?
  • 45.Python的zip函数有什么作用?
  • 46.请详细解释Python中`any()`和`all()`内置函数的作用
  • 47.为什么Python中没有函数重载?
  • 48.请介绍Python中变量的作用域(Scope)?
  • 49.什么是Python的闭包
  • 50.请详细说明Python中的内存管理机制
  • 51.请详细说明Python程序退出时内存的释放情况
  • 52.Python中是否有严格意义上的main函数?
  • 53.什么是Python的pickling和unpickling?
  • 54.什么是Python的猴子补丁(monkey patching)?
  • 55.什么是Python的鸭子类型(Duck Typing)
  • 56.什么是Python中的面向对象编程
  • 57.Python是否支持多重继承
  • 58.请详细说明Python3中装饰器的用法
  • 59.什么是Python中的模块和包?
  • 60.你使用过哪些Python标准库模块?
  • 61.你知道哪些Python魔术方法
  • 62.讲一下Python多线程、多进程和线程池
  • 63.如何分析Python代码的执行性能?
  • 64.pip
  • 65.pip-m
  • 67.uv
  • utf8
  • ast
  • dis
  • 尾递归
  • MethodType
  • 1. Unicode 转 UTF-8
    • 1.1 Unicode 是什么?
    • 1.2 UTF-8 是什么?
    • 1.3 为什么需要 UTF-8?
  • 2. UTF-8 编码规则
    • 2.1 编码规则表
    • 2.2 规则说明
  • 2.3 算法实现
    • 2.3.1 方法1:Python 内置方法(最简单)
    • 2.3.2 方法2:实现原理
  • 3.详细实例
    • 3.1 实例1:ASCII字符 'A'(1字节)
    • 3.2 实例2:汉字 '中'(3字节)
    • 3.3 实例3:Emoji '😀'(4字节)
  • 4.位运算
    • 4.1 关键运算符
    • 4.2 常用掩码
    • 4.3 位运算示例
  • 5. 总结

1. Unicode 转 UTF-8 #

1.1 Unicode 是什么? #

Unicode 是一个字符集标准,为世界上几乎所有的字符分配了一个唯一的编号,称为码点(Code Point)。

  • 表示方式:U+xxxx(十六进制)
  • 例如:
    • 'A' = U+0041 = 65(十进制)
    • '中' = U+4E2D = 20013(十进制)
    • '😀' = U+1F600 = 128512(十进制)

1.2 UTF-8 是什么? #

UTF-8 是 Unicode 的一种编码方式,将 Unicode 码点转换为字节序列,用于存储和传输。

1.3 为什么需要 UTF-8? #

  • Unicode 只定义了字符的编号,但没有规定如何在计算机中存储
  • UTF-8 是最流行的 Unicode 编码方式
  • 特点:
    • 变长编码(1-4字节)
    • 兼容 ASCII(ASCII字符只用1字节)
    • 节省空间

2. UTF-8 编码规则 #

2.1 编码规则表 #

Unicode 范围 十进制范围 字节数 UTF-8 编码格式 数据位数
U+0000 ~ U+007F 0 ~ 127 1字节 0xxxxxxx 7位
U+0080 ~ U+07FF 128 ~ 2047 2字节 110xxxxx 10xxxxxx 11位
U+0800 ~ U+FFFF 2048 ~ 65535 3字节 1110xxxx 10xxxxxx 10xxxxxx 16位
U+10000 ~ U+10FFFF 65536 ~ 1114111 4字节 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 21位

通常,在计算机领域里,FF 是十六进制表示法,写作 0xFF。
十六进制中:

  • F 代表十进制的 15
  • 每一位的权值是 16 的幂。

在十六进制中:F 代表十进制的 15 7F 可以看作是 7 * 16 + 15,所以 7 * 16 + 15 = 112 + 15 = 127 07FF 可以看作是 0x07FF = 7 × 16² + 15 × 16 + 15 = 1792 + 240 + 15 = 2047 FFFF 可以看作是 0xFFFF = 15 × 16³ + 15 × 16² + 15 × 16 + 15 = 61440 + 3840 + 240 + 15 = 65535 10FFFF 可以看作是 0x10FFFF = 1 × 16⁵ + 0 × 16⁴ + 15 × 16³ + 15 × 16² + 15 × 16 + 15 = 1048576 + 0 + 61440 + 3840 + 240 + 15 = 1114111

2.2 规则说明 #

  1. 首字节标识:通过首字节的前几位判断字节数

    • 0xxxxxxx:1字节(ASCII)
    • 110xxxxx:2字节的首字节
    • 1110xxxx:3字节的首字节
    • 11110xxx:4字节的首字节
  2. 后续字节标识:所有后续字节都以 10 开头

    • 这样可以区分首字节和后续字节
  3. 数据位填充:x 表示实际数据位

    • 将 Unicode 码点的二进制从低位到高位依次填入

2.3 算法实现 #

2.3.1 方法1:Python 内置方法(最简单) #

# 1.获取 Unicode 码点
码点 = ord('中')
print(f'U+{码点:04X}')  # U+4E2D
print(码点)  # 20013

# 2.从码点创建字符
字符 = chr(0x4E2D)
print(字符)  # '中'

# 3.Unicode 字符 → UTF-8 字节
utf8_bytes = '中'.encode('utf-8')
print(utf8_bytes)  # b'\xe4\xb8\xad'
print(utf8_bytes.hex())  # 'e4b8ad'

# 4.UTF-8 字节 → Unicode 字符
原字符 = utf8_bytes.decode('utf-8')
print(原字符)  # '中'

2.3.2 方法2:实现原理 #

# 定义函数,将Unicode码点转为UTF-8字节序列
def unicode_to_utf8(codepoint):
    """
    将 Unicode 码点转换为 UTF-8 字节序列

    参数:
        codepoint: Unicode 码点(整数)

    返回:
        bytes: UTF-8 编码的字节序列
    """
    # 检查码点是否在有效范围内
    if codepoint < 0 or codepoint > 0x10FFFF:
        raise ValueError(f"无效的 Unicode 码点: {codepoint}")

    # 如果码点小于等于0x7F,用1字节表示(ASCII)
    if codepoint <= 0x7F:
        # 构造单字节
        return bytes([codepoint])

    # 如果码点小于等于0x7FF,用2字节表示
    elif codepoint <= 0x7FF:
        # 构造第1字节(110xxxxx)
        byte1 = 0b11000000 | (codepoint >> 6)
        # 构造第2字节(10xxxxxx)
        byte2 = 0b10000000 | (codepoint & 0b00111111)
        # 返回组合后的2字节
        return bytes([byte1, byte2])

    # 如果码点小于等于0xFFFF,用3字节表示
    elif codepoint <= 0xFFFF:
        # 构造第1字节(1110xxxx)
        byte1 = 0b11100000 | (codepoint >> 12)
        # 构造第2字节(10xxxxxx)
        byte2 = 0b10000000 | ((codepoint >> 6) & 0b00111111)
        # 构造第3字节(10xxxxxx)
        byte3 = 0b10000000 | (codepoint & 0b00111111)
        # 返回组合后的3字节
        return bytes([byte1, byte2, byte3])

    # 其它情况,用4字节表示
    else:
        # 构造第1字节(11110xxx)
        byte1 = 0b11110000 | (codepoint >> 18)
        # 构造第2字节(10xxxxxx)
        byte2 = 0b10000000 | ((codepoint >> 12) & 0b00111111)
        # 构造第3字节(10xxxxxx)
        byte3 = 0b10000000 | ((codepoint >> 6) & 0b00111111)
        # 构造第4字节(10xxxxxx)
        byte4 = 0b10000000 | (codepoint & 0b00111111)
        # 返回组合后的4字节
        return bytes([byte1, byte2, byte3, byte4])

# 定义函数,将UTF-8字节序列转换为Unicode码点
def utf8_to_unicode(utf8_bytes):
    """
    将 UTF-8 字节序列转换为 Unicode 码点(反向转换)

    参数:
        utf8_bytes: UTF-8 编码的字节序列

    返回:
        int: Unicode 码点
    """
    # 检查输入是否为空
    if not utf8_bytes:
        raise ValueError("空字节序列")

    # 获取首字节
    first_byte = utf8_bytes[0]

    # 1字节编码情况:0xxxxxxx
    if (first_byte & 0b10000000) == 0:
        return first_byte

    # 2字节编码情况:110xxxxx 10xxxxxx
    elif (first_byte & 0b11100000) == 0b11000000:
        # 检查字节长度是否充足
        if len(utf8_bytes) < 2:
            raise ValueError("不完整的 UTF-8 序列")
        # 取高5位+低6位,拼出码点
        codepoint = ((first_byte & 0b00011111) << 6) | \
                    (utf8_bytes[1] & 0b00111111)
        return codepoint

    # 3字节编码情况:1110xxxx 10xxxxxx 10xxxxxx
    elif (first_byte & 0b11110000) == 0b11100000:
        # 检查字节长度是否充足
        if len(utf8_bytes) < 3:
            raise ValueError("不完整的 UTF-8 序列")
        # 拼接高4位、中间6位和低6位得码点
        codepoint = ((first_byte & 0b00001111) << 12) | \
                    ((utf8_bytes[1] & 0b00111111) << 6) | \
                    (utf8_bytes[2] & 0b00111111)
        return codepoint

    # 4字节编码情况:11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
    elif (first_byte & 0b11111000) == 0b11110000:
        # 检查字节长度是否充足
        if len(utf8_bytes) < 4:
            raise ValueError("不完整的 UTF-8 序列")
        # 拼接高3位、次高6位、次低6位和低6位得码点
        codepoint = ((first_byte & 0b00000111) << 18) | \
                    ((utf8_bytes[1] & 0b00111111) << 12) | \
                    ((utf8_bytes[2] & 0b00111111) << 6) | \
                    (utf8_bytes[3] & 0b00111111)
        return codepoint

    # 非法的UTF-8首字节
    else:
        raise ValueError("无效的 UTF-8 首字节")

# 测试代码:定义要测试的字符列表
test_chars = ['A', '中', '😀']
# 遍历每个字符
for char in test_chars:
    # 取出字符对应的Unicode码点
    codepoint = ord(char)

    # 手动将码点转为UTF-8字节序列
    utf8_manual = unicode_to_utf8(codepoint)

    # 用Python内置方法编码
    utf8_builtin = char.encode('utf-8')

    # 打印字符及转码信息
    print(f"\n字符: '{char}'")
    print(f"  Unicode码点: U+{codepoint:04X} ({codepoint})")
    print(f"  UTF-8字节: {utf8_manual.hex().upper()}")
    print(f"  字节数: {len(utf8_manual)}")
    print(f"  验证: {'正确' if utf8_manual == utf8_builtin else '错误'}")

    # 用自定义方法解码回码点
    decoded = utf8_to_unicode(utf8_manual)
    # 再转回字符
    decoded_char = chr(decoded)
    print(f"  反向解码: '{decoded_char}' (U+{decoded:04X})")

3.详细实例 #

3.1 实例1:ASCII字符 'A'(1字节) #

步骤分解:

1️⃣ Unicode 码点
   'A' = U+0041 = 65

2️⃣ 判断字节数
   65 ≤ 127,使用 1字节编码

3️⃣ 二进制表示
   65 = 0100 0001 (8位)

4️⃣ 应用编码格式
   格式:0xxxxxxx
   填充:0[1000001]

5️⃣ 结果
   字节1: 01000001 = 0x41

最终结果: 'A' → 41

3.2 实例2:汉字 '中'(3字节) #

步骤分解:


1️⃣ Unicode 码点
   '中' = U+4E2D = 20013

2️⃣ 判断字节数
   2048 ≤ 20013 ≤ 65535,使用 3字节编码

3️⃣ 二进制表示(16位)
   0x4E2D = 0100 1110 0010 1101
            ↓    ↓    ↓    ↓
            分组:0100 | 111000 | 101101
                 高4位  中6位   低6位

4️⃣ 应用编码格式
   格式:1110xxxx 10xxxxxx 10xxxxxx

   字节1: 1110[0100] = 11100100 = 0xE4
   字节2: 10[111000] = 10111000 = 0xB8
   字节3: 10[101101] = 10101101 = 0xAD

5️⃣ 位运算实现
   高4位 = (0x4E2D >> 12) & 0xF    = 0x4
   中6位 = (0x4E2D >> 6) & 0x3F    = 0x38
   低6位 = 0x4E2D & 0x3F           = 0x2D

   字节1 = 0b11100000 | 0x4  = 0xE4
   字节2 = 0b10000000 | 0x38 = 0xB8
   字节3 = 0b10000000 | 0x2D = 0xAD

最终结果: '中' → E4 B8 AD

3.3 实例3:Emoji '😀'(4字节) #

步骤分解:

1️⃣ Unicode 码点
   '😀' = U+1F600 = 128512

2️⃣ 判断字节数
   128512 > 65535,使用 4字节编码

3️⃣ 二进制表示(21位)
   0x1F600 = 0001 1111 0110 0000 0000
            ↓    ↓    ↓    ↓    ↓
            分组:000 | 011111 | 011000 | 000000
                 高3位 次高6位  次低6位  低6位

4️⃣ 应用编码格式
   格式:11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

   字节1: 11110[000] = 11110000 = 0xF0
   字节2: 10[011111] = 10011111 = 0x9F
   字节3: 10[011000] = 10011000 = 0x98
   字节4: 10[000000] = 10000000 = 0x80

5️⃣ 位运算实现
   高3位   = (0x1F600 >> 18) & 0x7  = 0x0
   次高6位 = (0x1F600 >> 12) & 0x3F = 0x1F
   次低6位 = (0x1F600 >> 6) & 0x3F  = 0x18
   低6位   = 0x1F600 & 0x3F         = 0x0

   字节1 = 0b11110000 | 0x0  = 0xF0
   字节2 = 0b10000000 | 0x1F = 0x9F
   字节3 = 0b10000000 | 0x18 = 0x98
   字节4 = 0b10000000 | 0x0  = 0x80

最终结果: '😀' → F0 9F 98 80

4.位运算 #

4.1 关键运算符 #

运算符 说明 示例
>> 右移(取高位) 0x4E2D >> 12 = 0x4
<< 左移(放大) 0x4 << 12 = 0x4000
& 按位与(提取) 0x4E2D & 0x3F = 0x2D
`\ ` 按位或(组合) `0xE0 \ 0x4=0xE4`

4.2 常用掩码 #

# 提取位的掩码
0b00111111  = 0x3F   # 提取低6位
0b00011111  = 0x1F   # 提取低5位
0b00001111  = 0x0F   # 提取低4位
0b00000111  = 0x07   # 提取低3位


# 标识位前缀
0b10000000  = 0x80   # 后续字节前缀
0b11000000  = 0xC0   # 2字节首字节前缀
0b11100000  = 0xE0   # 3字节首字节前缀
0b11110000  = 0xF0   # 4字节首字节前缀

4.3 位运算示例 #

# 示例:处理 '中' (U+4E2D)
codepoint = 0x4E2D  # 20013

# 提取各部分(3字节编码)
高4位 = (codepoint >> 12) & 0x0F        # 右移12位,取低4位 → 0x4
中6位 = (codepoint >> 6) & 0x3F         # 右移6位,取低6位 → 0x38
低6位 = codepoint & 0x3F                # 直接取低6位 → 0x2D

# 组装 UTF-8 字节
字节1 = 0b11100000 | 高4位              # 0xE0 | 0x4 = 0xE4
字节2 = 0b10000000 | 中6位              # 0x80 | 0x38 = 0xB8
字节3 = 0b10000000 | 低6位              # 0x80 | 0x2D = 0xAD

print(f"{字节1:02X} {字节2:02X} {字节3:02X}")  # E4 B8 AD

5. 总结 #

  1. Unicode 定义字符编号,UTF-8 定义存储方式
  2. UTF-8 是变长编码(1-4字节)
  3. 根据码点范围选择字节数
  4. 首字节和后续字节有固定的标识位
  5. 使用位运算提取和组合数据位
  6. Python 内置 encode()/decode() 方法最简单

访问验证

请输入访问令牌

Token不正确,请重新输入