飞翔飞翔
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
  • 数据库

    • SQL教程
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON教程
  • 工具

    • Markdown指南
  • Git

    • GitFlow
  • Quartz

    • Quartz教程
  • Java

    • Java设计模式
  • 缓存

    • Redis教程
联系
阿里云
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
  • 数据库

    • SQL教程
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON教程
  • 工具

    • Markdown指南
  • Git

    • GitFlow
  • Quartz

    • Quartz教程
  • Java

    • Java设计模式
  • 缓存

    • Redis教程
联系
阿里云
  • 学习路径
  • 第1章 认识Python

    • Python 历史与特点
    • Python 2 与 Python 3 的核心差异
    • 安装与运行 Python 2.7.18
    • 编码规范 PEP 8
  • 第2章 基础语法

    • 变量与对象
    • 数字类型
    • 字符串 str
    • Unicode 字符串
    • 运算符
    • 空值 None
  • 第3章 流程控制

    • if 条件语句
    • if-else 条件语句
    • if-elif-else 多分支
    • 条件表达式(三元运算符)
    • while 循环
    • for 循环
    • range 与 xrange
    • 循环控制:break、continue、pass
    • 循环 else 子句
  • 第4章 数据结构

    • 列表基础
    • 列表方法
    • 列表推导式
    • 元组
    • 字典基础
    • 字典方法
    • 字典循环技巧
    • 集合
    • 序列解包
    • 序列比较
  • 第5章 函数

    • 定义函数
    • 参数传递机制
    • 默认参数
    • 关键字参数
    • 可变参数
    • Lambda 表达式
    • 文档字符串
    • 函数对象
  • 第6章 模块与包

    • import 导入
    • 模块搜索路径
    • name 与主程序
    • 编译文件 .pyc 与 .pyo
    • 包结构
    • dir() 函数
  • 第7章 文件与IO

    • 打开与关闭文件
    • 文件读写方法
    • with 上下文管理器
    • 格式化输出:% 操作符
    • 格式化输出:str.format()
    • JSON 序列化
  • 第8章 面向对象

    • 类定义与实例化
    • init 构造方法
    • 类变量与实例变量
    • 方法调用与 self
    • 继承基础
    • 多重继承
    • 新式类与旧式类
    • 私有变量与名称改写
    • 属性装饰器 property
    • 类方法与静态方法
    • 魔术方法
    • 空类与数据记录
  • 第9章 异常处理

    • 异常类型
    • try-except
    • try-except-else-finally
    • 抛出异常 raise
    • 自定义异常
    • with 语句与上下文管理器
  • 第10章 迭代器与生成器

    • 迭代器协议
    • 生成器函数
    • 生成器表达式
    • itertools模块
  • 第11章 标准库精要

    • os模块
    • sys模块
    • datetime模块
    • re模块
    • json模块
    • collections模块
    • math与random模块
    • urllib2与网络请求
    • subprocess与命令执行
    • threading与并发
    • unittest与测试
    • 虚拟环境与包管理
  • 第12章 工程实践

    • 调试技巧
    • 性能分析
    • 文档与注释
    • 下一步学习

字符串 str

在 Python 2 中,str 是字节串(byte string),而非字符序列。每个元素是一个字节(0–255 的整数),在 ASCII 范围内(0–127)可以表示英文字母、数字和常见符号。这是 Python 2 字符串系统最容易被误解的地方,也是它与 Python 3 最根本的差异之一。

创建字符串

s1 = 'hello'            # 单引号
s2 = "world"            # 双引号
s3 = '''多行
字符串'''               # 三引号,保留换行
s4 = """也可以
用双引号"""

单引号和双引号完全等价,选择哪个取决于字符串内容:如果字符串包含单引号,就用双引号包裹,反之亦然。这样可以避免转义:

print "It's a nice day"     # 正确
print 'It\'s a nice day'   # 也可以,但多了反斜杠

字符串是不可变的

str 是不可变序列,创建后不能修改任何字符:

s = "hello"
s[0] = "H"              # TypeError: 'str' object does not support item assignment

所有看似"修改"字符串的操作,实际上都是创建新字符串:

s = "hello"
s2 = s.capitalize()     # 创建新字符串 "Hello",s 不变
print s                 # "hello"
print s2                # "Hello"

这种不可变性带来了两个好处:一是字符串可以作为字典的键(字典键必须可哈希,而可变对象不可哈希);二是多个变量可以安全地共享同一个字符串对象,无需担心被意外修改。

索引与切片

字符串支持序列的所有标准操作:

s = "Python"

# 索引
print s[0]          # 'P'
print s[-1]         # 'n',倒数第一个

# 切片 [start:stop:step]
print s[0:2]        # 'Py',左闭右开
print s[2:]         # 'thon',从索引 2 到末尾
print s[:4]         # 'Pyth',从开头到索引 4(不含)
print s[::2]        # 'Pto',每隔一个取一个
print s[::-1]       # 'nohtyP',反转

切片不会越界报错,而是自动截断到有效范围:

s = "hi"
print s[0:100]      # 'hi',不会报错
print s[5:10]       # '',空字符串

转义序列

反斜杠 \ 用于引入特殊字符:

print "Line 1\nLine 2"      # \n 换行
print "Tab\there"           # \t 制表符
print "C:\\Users\\Bob"      # \\ 反斜杠本身
print 'It\'s mine'          # \' 单引号
print "She said \"Hi\""     # \" 双引号

如果字符串中包含大量反斜杠(如 Windows 路径、正则表达式),可以使用原始字符串(raw string),前缀加 r 或 R:

path = r"C:\Users\Bob\Documents"
print path              # C:\Users\Bob\Documents,不处理转义

pattern = r"\b\w+@\w+\.\w+"
print pattern           # \b\w+@\w+\.\w+,正则表达式保留原样

注意:原始字符串的末尾不能是单个反斜杠,因为反斜杠会转义引号:r"C:\" 是语法错误。解决方法是拼接:r"C:\" + "\\" 或 "C:\\\"。

常用方法

s = "  Hello, World!  "

print s.strip()         # "Hello, World!",去除两端空白
print s.lower()         # "  hello, world!  "
print s.upper()         # "  HELLO, WORLD!  "
print s.startswith("He")    # False(前面有空格)
print s.find("World")       # 10,找不到返回 -1
print s.replace("World", "Python")  # "  Hello, Python!  "
print s.split(", ")          # ['  Hello', 'World!  ']
print "-".join(["a", "b", "c"])   # "a-b-c"

find() 和 index() 的区别:find() 找不到返回 -1,index() 找不到抛出 ValueError:

print "abc".find("z")       # -1
print "abc".index("z")      # ValueError: substring not found

字符串格式化

Python 2 中最常用的格式化方式是 % 操作符:

name = "Alice"
age = 25
print "My name is %s, I am %d years old." % (name, age)
# My name is Alice, I am 25 years old.

常用格式符:

格式符含义示例
%s字符串"%s" % "hello" → "hello"
%d整数"%d" % 42 → "42"
%f浮点数"%f" % 3.14 → "3.140000"
%.2f保留两位小数"%.2f" % 3.14159 → "3.14"
%x十六进制"%x" % 255 → "ff"
%o八进制"%o" % 8 → "10"
%%字面量 %"100%%" → "100%"

str.format()(Python 2.6+)提供了更灵活的格式化:

print "{0} + {1} = {2}".format(1, 2, 3)           # "1 + 2 = 3"
print "{name} is {age} years old".format(name="Tom", age=20)

编码陷阱

str 本质上是字节序列,它不知道自己的编码。如果文件头声明了 UTF-8,源文件中的 "你好" 会被编码为 6 个字节(\xe4\xbd\xa0\xe5\xa5\xbd),存储在 str 对象中。打印时,终端需要知道这 6 个字节是 UTF-8 编码,才能正确显示"你好"。

如果终端编码与文件编码不一致,就会出现乱码或 UnicodeEncodeError。这是 Python 2 字符串系统最痛苦的地方,也是 Python 3 将 str 改为 Unicode 的根本原因。

上一页
数字类型
下一页
Unicode 字符串