字符串格式化、文件操作、异常处理
字符串格式化
f-string
3.6 之后版本支持的格式化字符串,在字符串的引号前加上 f
,通过 {}
来引用变量或者表达式。
name = 'Alice'
age = 25
print(f'My name is {name} and I am {age} years old.')
除了常规的输出,还可以用来格式化时间,数字等。
import datetime
now = datetime.datetime.now()
print(f'The current time is {now: %Y-%m-%d %H:%M:%S}.')
冒号后可以指定格式化字符串,比如 %Y-%m-%d %H:%M:%S
表示年月日时分秒。也可以针对数字做出操作,比如 {num:.2f}
表示保留两位小数,会自动四舍五入。
假设你有一个很大的数字 100000 想格式化为 100,000,可以使用 {num:,}
来实现。再保留两位小数,可以使用 {num:,.2f}
来实现。
输出的对齐,可以使用 {num:>10}
来实现,表示右对齐,{num:<10}
表示左对齐,{num:^10}
表示居中对齐。默认情况下是左对齐。并且会用空格填充。也可以指定填充的内容。
num = 123
print(f'{num:>10}')
print(f'{num:<10}')
print(f'{num:^10}')
print(f'{num:*^10}')
format 方法
基本与 f-string
类似,但是需要使用 {}
来引用变量或者表达式。
print('Hello {}!'.format(name))
print('{:%Y-%m-%d %H-%M-%S}'.format(datetime.datetime.now()))
print('{:.2f}'.format(1000))
print('{:,.2f}'.format(1000))
print('{:>10}'.format(1000))
print('{:<10}'.format(1000))
print('{:^10}'.format(1000))
多个参数时,可以使用 {index}
来指定参数的索引。也可以使用 {key}
来指定参数的键。
print('{0}, {1}'.format(name, age))
print('{1}, {0}'.format(age, name))
print('{name} {age}'.format(name='Alice', age=25))
print('{name} {age}'.format(age=25, name='Alice'))
旧式格式化
3.6 之前版本支持的格式化字符串,使用 %
来引用变量或者表达式。
print('%s %d' % (name, age))
print('%d %s' % (age, name))
%
为占位符,%s
表示字符串,%d
表示整数,%f
表示浮点数。
文件操作
open 函数用于打开文件,返回一个文件对象。有三种模式:
r
读取模式,默认模式。w
写入模式,会覆盖原有文件。a
追加模式,在原有文件基础上追加内容。b
二进制模式,用于读取二进制文件。r+
读写模式,可以读取和写入文件。w+
写读模式,可以写入和读取文件。a+
追加读模式,可以追加和读取文件。b+
二进制读写模式,可以读取和写入二进制文件。
encoding 参数用于指定文件的编码格式,如果不指定,则使用系统默认编码。
file = open('test.txt', 'r', encoding='utf-8')
print(file.closed) # False
file.close()
print(file.closed) # True
open 的方式需要手动的关闭文件,可以使用 with 语句来自动关闭文件。
with open('test.txt', 'r', encoding='utf-8') as file:
print(file.read())
print(file.closed) # True
文件的读写方法
方法 | 描述 |
---|---|
read(size=-1) | 读取文件内容,size 为读取的字节数,默认读取全部 |
readline(size=-1) | 读取文件的一行内容,size 为读取的字节数,默认读取整行 |
readlines(hint=-1) | 读取文件的所有行内容,hint 为读取的行数,默认读取所有行 |
write(str) | 写入字符串内容到文件 |
writelines(lines) | 写入字符串列表到文件,每个元素为一行 |
seek(offset, whence=0) | 移动文件指针,offset 为偏移量,whence 为起始位置(0开头,1当前,2结尾) |
tell() | 获取文件指针当前位置 |
close() | 关闭文件 |
readable() | 判断文件是否可读 |
writable() | 判断文件是否可写 |
closed | 判断文件是否已关闭 |
with open('test.txt', 'r', encoding='utf-8') as file:
print(file.readable())
print(file.writable())
print(file.closed)
readline 如果返回空字符串,标识文件句柄已经到达文件末尾。
seek 方法用于移动文件指针,可以指定偏移量和起始位置。默认从 0 开始。
# 在距离文件开头 50 字节处开始写入内容
with open('test.txt', 'r+', encoding='utf-8') as file:
file.seek(50)
file.write('Hello, world!')
json 序列化
json 是 JavaScript Object Notation 的缩写,是一种轻量级的数据交换格式。
json 序列化:将 Python 对象转换为 json 字符串。
json 反序列化:将 json 字符串转换为 Python 对象。
import json
# 序列化
json_str = json.dumps(data)
# 反序列化
data = json.loads(json_str)
错误和异常
语法错误又称为解析错误,指代码不符合 Python 语法规则。
while True print('Hello world')
File "<stdin>", line 1
while True print('Hello world')
^^^^^
SyntaxError: invalid syntax
异常指程序运行时发生的错误,比如除以 0,文件不存在等。 在报错信息中,最后一行是异常类型,前面是异常发生的文件和行号。
Traceback (most recent call last):
File "/Users/xushuqing/Documents/learn-codes/learn-python/code_1.py", line 45, in <module>
print(10 / 0)
ZeroDivisionError: division by zero
异常也分为内置异常和自定义异常。常见的异常多种多样,实际问题实际解决。https://docs.python.org/zh-cn/3/library/exceptions.html#bltin-exceptions
异常的处理
while True:
try:
x = int(input("Please enter a number: "))
break
except ValueError:
print("Oops! That was no valid number. Try again...")
try
语句用于捕获异常,except
语句用于处理异常,finally
语句用于执行清理操作。finally
语句是可选的,用于执行一些清理操作,比如关闭文件,释放资源等。
如果被 try
包裹的代码块没有发生异常,则 except
语句不会被执行。finally
语句会始终被执行。
一个 except
语句可以捕获多个异常,使用元组来表示。但不会同时捕获多个异常。
try:
print(10 / 0)
except (ZeroDivisionError, ValueError):
print("Oops! That was no valid number. Try again...")
在自定义的异常中,可以继承内置异常,并添加自己的异常信息。多个 except
语句可以捕获不同的异常。如果多个异常类则匹配到基类, 如果基类匹配到则不会继续往下执行 如下
class A(Exception):
pass
class B(A):
pass
class C(B):
pass
# 打印 A A A
for i in [A, B]:
try:
raise i()
except A:
print("A")
except B:
print("B")
except C:
print("C")
# 打印 A B C
for i in [A, B]:
try:
raise i()
except C:
print("C")
except B:
print("B")
except A:
print("A")
触发异常
raise 语句用于触发异常。参数必须是异常类或者异常实例。
raise ValueError('错误信息')
异常 | 描述 |
---|---|
Exception | 所有异常的基类 |
ValueError | 值错误 |
TypeError | 类型错误 |
NameError | 名称错误 |
IndexError | 索引错误 |
KeyError | 键错误 |
FileNotFoundError | 文件未找到错误 |
ZeroDivisionError | 除以 0 错误 |
StopIteration | 迭代器没有更多的值 |
KeyboardInterrupt | 用户中断执行 |
SystemExit | 解释器请求退出 |
MemoryError | 内存溢出错误 |
ImportError | 导入模块/对象失败 |
AttributeError | 对象没有这个属性 |
无脑的 异常处理 - 捕获所有异常
try:
raise Exception('错误信息')
except Exception as e:
# 实际开发的时候可以使用这个先兜底
print(e)
练习题
基础练习
字符串格式化
python# 有以下变量: name = "Alice" age = 25 height = 1.68 # 使用三种不同的字符串格式化方式完成以下输出: # "My name is Alice, I'm 25 years old and 1.68m tall." # 要求:height 保留两位小数
文件读写
python# 创建一个程序,要求: # 1. 创建一个文件 'names.txt',写入三个名字,每个名字占一行 # 2. 读取文件内容,将每个名字转换为大写 # 3. 将转换后的内容写入新文件 'upper_names.txt'
JSON 处理
python# 有以下 Python 字典: student = { 'name': 'Bob', 'age': 20, 'scores': { 'math': 95, 'english': 89, 'history': 92 } } # 要求: # 1. 将字典转换为 JSON 字符串 # 2. 将 JSON 字符串保存到文件 # 3. 从文件读取 JSON 字符串并转换回 Python 对象
进阶练习
文件处理与异常处理
python# 编写一个函数 safe_read_file(filename),要求: # 1. 读取指定的文本文件内容 # 2. 处理可能发生的异常(文件不存在、权限不足等) # 3. 如果文件不存在,返回"File not found" # 4. 如果读取成功,返回文件内容
高级字符串格式化
python# 创建一个函数 format_student_info(students),接收一个学生列表: students = [ {'name': 'Alice', 'age': 25, 'score': 95}, {'name': 'Bob', 'age': 23, 'score': 88}, {'name': 'Charlie', 'age': 24, 'score': 92} ] # 要求: # 1. 输出一个格式化的表格,包含姓名、年龄和分数 # 2. 分数需要显示为百分比形式(95.00%) # 3. 表格要求左对齐
挑战题
- 成绩单处理程序python
# 实现一个成绩单处理程序,要求: # 1. 从文件 'scores.txt' 中读取学生成绩数据 # 文件格式:每行一条记录,格式为 "姓名,分数" # 例如: # Alice,95 # Bob,88 # Charlie,92 # 2. 处理数据并计算: # - 班级平均分 # - 最高分和最低分 # - 分数段统计(90-100, 80-89, 70-79, 60-69, <60) # 3. 将统计结果保存为 JSON 格式的文件 # 4. 处理所有可能的异常(文件不存在、格式错误等)
参考答案
点击查看答案
基础练习答案
字符串格式化
pythonname = "Alice" age = 25 height = 1.68 # f-string print(f"My name is {name}, I'm {age} years old and {height:.2f}m tall.") # format 方法 print("My name is {}, I'm {} years old and {:.2f}m tall.".format(name, age, height)) # % 操作符 print("My name is %s, I'm %d years old and %.2fm tall." % (name, age, height))
文件读写
python# 写入原始文件 with open('names.txt', 'w', encoding='utf-8') as f: f.write('alice\nbob\ncharlie\n') # 读取并转换 with open('names.txt', 'r', encoding='utf-8') as f: names = [name.strip().upper() for name in f.readlines()] # 写入新文件 with open('upper_names.txt', 'w', encoding='utf-8') as f: f.write('\n'.join(names) + '\n')
JSON 处理
pythonimport json student = { 'name': 'Bob', 'age': 20, 'scores': { 'math': 95, 'english': 89, 'history': 92 } } # 转换为 JSON 字符串 json_str = json.dumps(student, indent=4) # 保存到文件 with open('student.json', 'w') as f: f.write(json_str) # 读取并转换回 Python 对象 with open('student.json', 'r') as f: loaded_student = json.loads(f.read()) print(loaded_student == student) # True
进阶练习答案
文件处理与异常处理
pythondef safe_read_file(filename): try: with open(filename, 'r', encoding='utf-8') as f: return f.read() except FileNotFoundError: return "File not found" except PermissionError: return "Permission denied" except Exception as e: return f"Error: {str(e)}"
高级字符串格式化
pythondef format_student_info(students): # 创建表头 header = f"{'Name':<10}{'Age':<6}{'Score':<8}" separator = "-" * 24 # 创建数据行 rows = [] for student in students: row = f"{student['name']:<10}{student['age']:<6}{student['score']:.2f}%" rows.append(row) # 组合所有行 return "\n".join([header, separator] + rows)
挑战题答案
- 成绩单处理程序python
import json from collections import defaultdict def process_scores(filename): try: # 读取文件 scores = [] with open(filename, 'r', encoding='utf-8') as f: for line in f: name, score = line.strip().split(',') scores.append((name, float(score))) # 计算统计数据 score_values = [score for _, score in scores] stats = { 'average': sum(score_values) / len(score_values), 'highest': max(score_values), 'lowest': min(score_values), 'distribution': { '90-100': len([s for s in score_values if 90 <= s <= 100]), '80-89': len([s for s in score_values if 80 <= s < 90]), '70-79': len([s for s in score_values if 70 <= s < 80]), '60-69': len([s for s in score_values if 60 <= s < 70]), '<60': len([s for s in score_values if s < 60]) } } # 保存结果 with open('score_stats.json', 'w', encoding='utf-8') as f: json.dump(stats, f, indent=4) return stats except FileNotFoundError: return "Error: File not found" except ValueError: return "Error: Invalid file format" except Exception as e: return f"Error: {str(e)}" # 测试代码 if __name__ == "__main__": result = process_scores('scores.txt') print(result)
TIP
建议先独立完成练习,遇到困难时再参考答案。这样能够更好地掌握所学知识。