【Python】Python基础补全

  • ~8.11K 字
  1. 1. 字符串格式化
    1. 1.1. %格式化
    2. 1.2. str.format()
      1. 1.2.1. 基本语法与参数
      2. 1.2.2. 格式规范和类型转换
      3. 1.2.3. 嵌套与自定义
    3. 1.3. f-string
      1. 1.3.1. 基本语法与格式控制
      2. 1.3.2. 高级特性
  2. 2. 异常处理
    1. 2.1. Python对异常的表现
    2. 2.2. 常见异常
    3. 2.3. 处理异常的语法
      1. 2.3.1. 获取异常信息
      2. 2.3.2. 捕获多个异常
    4. 2.4. 异常的主动触发与传递
      1. 2.4.1. 主动触发异常
      2. 2.4.2. 重新抛出异常
      3. 2.4.3. 异常的传递
    5. 2.5. 自定义异常
      1. 2.5.1. 定义
      2. 2.5.2. 触发
      3. 2.5.3. 继承
  3. 3. 文件操作
    1. 3.1. 基础文件操作
    2. 3.2. 文件打开模式
    3. 3.3. 基础操作
    4. 3.4. 二进制文件
    5. 3.5. 文件读取方式
    6. 3.6. 文件写入方式
    7. 3.7. 文件指针
    8. 3.8. 文件属性和元数据

字符串格式化

%格式化

基本语法:模板字符串 % (值1, 值2,...)

模板字符串里的占位符以%+类型说明符表示,具体占位符如下

占位符 含义
%s 字符串
%r 原始调用(repr())
%d 十进制整数
%f 浮点数

%占位符还支持通过格式说明符控制输出格式,语法如下:

%[宽度][.精度][类型]

  • 宽度指定输出字符串的最小长度,不足用空格填充,默认右对齐
  • 精度:对浮点数表示小数位数,对字符串表示最大长度
  • 左对齐:宽度前加-实现左对齐

不好用

str.format()

基本语法与参数

基本语法:模板字符串.format(参数1, 参数2, ..., 关键字参数1=值1, ...)

模板字符串中使用{}占位符在模板中预留位置

位置参数:占位符中可以用数字指定参数索引,或省略按顺序匹配

1
2
3
4
5
# 按顺序匹配
print("Name: {}, Age: {}".format("lihua", 18))

# 按索引指定(可重复/乱序)
print("Second: {1}, First: {0}, First again: {0}".format("A", "B"))

关键字参数:占位符中也可以直接用关键字参数名

1
print("User: {name}, ID: {id}".format(name="lihua", id=114514))

混合使用:可以混合使用,但是位置参数必须在关键字参数前

1
print("{}: {name} ({age})".format("person", name="lihua", age=18))

格式规范和类型转换

format方法支持通过:在占位符中添加格式规范,语法形如{[名称/索引]:[格式规范]}

  • 对齐和宽度:

    • <是左对齐
    • >是右对齐
    • ^是居中对齐
    • 符号后可以添加数字指定对齐后的字符串长度
  • 浮点数精度:{:.位数f}

  • 千位分隔符:{:,},只适用于数字

  • 类型转换符:{!类型},指定类型转换,类似于%s或%r,对应字母一样

  • 特定类型格式化:

    • 日期:{:%Y-%m-%d %H:%M}
    • 百分比:{:.位数%}

嵌套与自定义

  • 可以嵌套列表和字典:
1
2
3
4
stu = {"name": "lihua", "age": 18}
classes = ["class1", "class2"]

print("Name: {s['name']}, Hobby: {c[0]}".format(s=stu, c=classes))
  • 可以调用对象方法:可以调用无参数的对象方法
1
2
text = "hello world"
print("{.upper()}".format((text)))
  • 自定义格式化逻辑:在类中实现__format__方法,可以自定义对象的格式化行为
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Temperature:
def __init__(self, celsius):
self.celsius = celsius

# 自定义格式化:支持 'c'(摄氏度)和 'f'(华氏度)
def __format__(self, format_spec):
if format_spec == 'f':
fahrenheit = self.celsius * 9/5 + 32
return f"{fahrenheit:.1f}°F"
else: # 默认摄氏度
return f"{self.celsius:.1f}°C"

temp = Temperature(25)
print("Temp: {t:c}".format(t=temp)) # 输出:Temp: 25.0°C
print("Temp: {t:f}".format(t=temp)) # 输出:Temp: 77.0°F

f-string

格式化字符字面值,在字符串前加f或F前缀,在字符串中用{}嵌入变量或表达式

它的性能更快,安全性更高

基本语法与格式控制

f"模板字符串, {变量/表达式}会被替换为值"

1
2
3
name = 'lihua'
age = 18
print(f"name: {name}, age: {age}")

格式控制语法:{表达式:格式规范}

与format相同的格式规范

高级特性

f-string 支持在{}中嵌入任意合法的Python表达式,包括函数调用、三目运算等

  • 函数调用:直接在占位符中调用函数
1
2
3
4
def hello(name):
return f"hello {name}"
name = 'lihua'
print(f"{hello(name)}")
  • 三目运算:
1
2
score = 80
print(f{'pass' if score>=60 else 'failed'})
  • 嵌套结构访问:
1
2
3
stu = {"name": "lihua", "age": 18}
classes = ["class1", "class2"]
print(f"student: {stu['name']}, class: {class[0]}")
  • 多行f-string:使用三引号支持多行模板
1
2
3
4
5
6
7
8
9
name = 'lihua'
age = 18
score = 80
bio = f"""
student info:
- name: {name}
- age: {age}
- score: {'pass' if score>=60 else 'failed'}
"""

异常处理

Python对异常的表现

当发生异常时,python会生成一个异常对象,包含错误类型、描述和发生位置

若未捕获,程序终止并打印回溯信息(Traceback),显示异常类型和发生位置

常见异常

常见异常类型如下:

异常类型 说明
SyntaxError 语法错误
NameError 使用了未定义的变量
TypeError 操作或函数应用于不适当类型
ValueError 参数类型正确,但值不合法
IndexError 索引超出序列范围
KeyError 字典中不存在指定键
AttributeError 对象没有指定属性或方法
ZeroDivisionError 除数为 0
FileNotFoundError 文件不存在
IOError / OSError 输入输出操作错误
ImportError 导入模块失败
ModuleNotFoundError 找不到指定模块
EOFError 输入到达文件末尾
RuntimeError 一般运行时错误
MemoryError 内存不足
OverflowError 数值运算结果超出范围
RecursionError 递归层数超过限制
AssertionError assert 断言失败
StopIteration 迭代器没有更多元素
KeyboardInterrupt 用户按下 Ctrl+C 中断程序

处理异常的语法

Python使用try-catch语句块捕获并处理异常,结构如下:

1
2
3
4
5
6
7
8
9
10
try:
risk_operation()
except 异常类型1:
# 处理异常1的代码
except 异常类型2 as e:
# 处理异常2的代码,e是异常对象
else:
# 无异常时执行的代码(可选)
finally:
# 无论是否有异常都执行的代码(可选)

获取异常信息

使用as e捕获异常对象,进而提取异常详情

1
2
3
4
5
6
try:
int('a')
except ValueError as e:
print("异常类型: ", type(e))
print("异常描述: ", e)
print("异常参数: ", e.args)

捕获多个异常

  • 一个try后可以接多个catch,处理不同异常
  • 使用except Exception捕获所有非系统退出类异常

异常的主动触发与传递

主动触发异常

使用raise可以手动触发异常,用于验证合法性或标记未实现的功能

1
2
3
4
5
6
7
8
9
def register(username):
if len(username) < 3:
# 主动触发 ValueError
raise ValueError(f"用户名 '{username}' 太短,至少需要3个字符")
print(f"'{username}' 注册成功")

try:
register("ab") # 长度不足,触发异常
except ValueError as e:

重新抛出异常

捕获异常后,若无法处理,可以用raise重新抛出,让上层代码处理,此时raise不带参数

1
2
3
4
5
6
7
8
9
10
11
12
ef read_data(filename):
try:
with open(filename, "r") as f:
return f.read()
except FileNotFoundError as e:
print(f"read_data 函数捕获到错误:{e}")
raise # 重新抛出异常,让调用者处理

try:
data = read_data("nonexist.txt")
except FileNotFoundError as e:
print(f"主程序处理错误:{e}")

异常的传递

若函数内发生异常且未捕获,异常会向上传递至调用者,直至被捕获或程序崩溃

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def f3():
print("进入f3")
x = int("abc") # ValueError
print("离开f3")

def f2():
print("进入f2")
f3()
print("离开f2")

def f1():
print("进入f1")
f2()
print("离开f1")

try:
f1()
except ValueError as e:
print("捕获异常:", e)

结果为:

1
2
3
4
进入f1
进入f2
进入f3
捕获异常: invalid literal for int() with base 10: 'abc'

如果想要在中间层处理后继续传递,使用raise

自定义异常

定义

当内置异常无法满足要求时,可以继承Exception类自定义异常

1
2
3
4
5
6
7
8
9
10
11
# 定义自定义异常(继承 Exception)
class InvalidAgeError(Exception):
"""当年龄不合法时触发的异常"""
def __init__(self, age, message="年龄必须在 0-120 之间"):
self.age = age
self.message = message
super().__init__(self.message) # 调用父类构造函数

# 可选:自定义异常描述
def __str__(self):
return f"{self.message},实际输入:{self.age}"

触发

1
2
3
4
5
6
7
8
9
10
def check_age(age):
if not (0 <= age <= 120):
# 触发自定义异常
raise InvalidAgeError(age)
print(f"年龄 {age} 合法")

try:
check_age(150) # 超出范围,触发异常
except InvalidAgeError as e:
print("检查失败:", e) # 输出:检查失败:年龄必须在 0-120 之间,实际输入:150

继承

自定义异常可以继承,用于创建更细分的异常类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 基础异常
class ValidationError(Exception):
pass

# 细分异常(继承自 ValidationError)
class TooSmallError(ValidationError):
pass

class TooLargeError(ValidationError):
pass

def validate_number(n):
if n < 0:
raise TooSmallError(f"{n} 不能小于 0")
if n > 100:
raise TooLargeError(f"{n} 不能大于 100")
print(f"{n} 验证通过")

try:
validate_number(-5)
except TooSmallError as e:
print("处理过小错误:", e)
except TooLargeError as e:
print("处理过大错误:", e)
except ValidationError as e: # 捕获所有子类异常
print("处理其他验证错误:", e)

文件操作

基础文件操作

open()函数是文件操作的入口,用于打开文件返回文件对象,语法如下:

1
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
  • file是文件路径,传入字符串或Path对象
  • mode是打开模式,决定读写权限和文件类型
  • encoding是文本模式下的编码格式

文件打开模式

  • 只读:r
  • 只写:w
  • 追加:a
  • 读写(保留原内容):r+
  • 读写(清空原内容):w+
  • 追加+读:a+

基础操作

需要遵循“打开->操作->关闭”的流程,防止资源泄露

一般使用with语句(即上下文管理器)自动关闭文件,无需手动关闭

1
2
3
4
5
6
7
# 写入
with open('test.txt', 'w', encoding='utf-8') as f:
f.write('hello world!\n')
# 读取
with open('test.txt', 'r', encoding='utf-8') as f:
content = f.read()
print(content)

二进制文件

二进制文件需要在操作后加一个b(有加号的在加号前)

1
2
3
with open('test.jpg', 'rb') as src, open('copy.jpg', 'wb') as dst:
data = src.read()
dst.write(data)

文件读取方式

方法 功能说明 适用场景
read() 无参:读取全部内容;
有参 n:读取至多 n 字节(二进制模式常用)
小文件(一次性处理全文);
二进制大文件分块处理(如网络传输、分片复制)
readline() 读取一行内容(含换行符 \n),支持指定字节限制 limit 按行处理文件(如日志解析、CSV逐行读取);超大行文件(指定 limit 控制内存)
readlines() 读取所有行,返回列表(每行作为元素,含换行符 \n) 中等大小文件,需按行索引访问(如按行号提取内容)或批量处理所有行
迭代文件对象 (for line in f) 自动逐行读取,循环内每次返回一行(含换行符 \n),底层调用 readline() 大/超大文件(内存友好,无需一次性加载全部内容),仅需顺序处理行数

文件写入方式

方法 功能说明 适用场景
write(str) 写入字符串,返回写入的字符数 单次写入一个完整的字符串;需要精确控制写入内容(如构建自定义格式)
writelines(seq) 写入字符串序列(列表/元组等),不自动添加换行符 批量写入多个字符串;当序列中的每个元素己包含换行符,或不需要分隔符时
print(..., file=f) 用 print 函数写入,可自动添加换行符(end 参数控制) 快速写入并自动换行;需要灵活控制输出格式(如自定义分隔符、末尾字符)

文件指针

方法/属性 功能说明
tell() 返回当前指针位置(字节数)
seek(offset, whence) 移动指针到指定位置:offset 偏移量(正数向后,负数向前);
whence 基准位置(0:文件开头,1:当前位置,2:文件末尾)

e.g.

1
2
3
4
5
6
7
8
9
10
11
12
with open('test.txt', 'w+', encoding='utf-8') as f:
f.write('0123456789')
print('写后指针位置:', f.tell()) # 指针此时在文件末尾,输出10

# 从当前位置移动
f.seek(2,1) # 从当前位置开始计算,移动两位
print(f.read())
print(f.tell())

# 从文件末尾移动
f.seek(-3,2) # 从末尾开始计算,移动三位
print(f.read())

文件属性和元数据

通过os或pathlib库可以获取文件的元数据

  • Path():路径类,可以便捷创建路径
  • .exists():判断文件是否存在
  • .is_file():判断是否为文件
  • .is_dir():判断是否为目录
  • Path().mkdir(parents=True, exist_ok=True):创建目录,parents为自动创建上层目录,exist——ok为存在时不报错
  • .stat().st_size:文件大小(字节)
  • .stat().st_ctime:创建时间
  • .stat().st_mtime:最后修改时间
赞助喵
非常感谢您的喜欢!
赞助喵