学习日志17 python
1 open()
方法与文件系统交互
在 Python 中,open()
方法用于与文件系统交互,创建一个文件对象以便对文件进行读写操作。
其完整语法如下:
python
运行
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
核心参数详解
file
(必需)
文件路径(相对或绝对路径),例如:'data.txt'
或'/home/user/docs/report.csv'
。mode
(可选)
指定文件打开方式,默认值为'r'
(只读模式)。常用模式包括:'r'
:只读,文件必须存在。'w'
:写入,会覆盖原有文件(若存在);不存在则创建。'a'
:追加,在文件末尾添加内容,不存在则创建。'x'
:独占创建,文件不存在时创建,存在则报错。- 扩展字符:
'b'
:二进制模式(如'rb'
表示二进制只读)。'+'
:读写模式(如'r+'
表示可读可写)。
encoding
(可选)
指定文件编码格式(如'utf-8'
、'gbk'
),仅适用于文本模式。默认使用系统编码(如locale.getpreferredencoding()
)。errors
(可选)
指定编码错误的处理方式,例如:'ignore'
:忽略错误。'replace'
:用?
替换非法字符。'strict'
:抛出UnicodeDecodeError
(默认值)。
newline
(可选)
控制换行符的处理(仅文本模式有效):None
:统一处理'\n'
、'\r'
、'\r\n'
为'\n'
(默认值)。''
:不转换换行符。'\n'
、'\r'
等:按指定字符识别换行符。
常用示例
1. 读取文件
python
运行
# 文本模式(默认)
with open('data.txt', 'r', encoding='utf-8') as f:content = f.read() # 读取全部内容# 二进制模式(如读取图片)
with open('image.jpg', 'rb') as f:data = f.read()
2. 写入文件
python
运行
# 覆盖写入
with open('output.txt', 'w') as f:f.write('Hello, World!\n')# 追加写入
with open('output.txt', 'a') as f:f.write('Appended line.\n')
3. 读写模式
python
运行
# 读写模式(文件需存在)
with open('data.txt', 'r+') as f:content = f.read() # 先读取f.write('New content') # 写入到文件末尾
文件对象的常用方法
读取方法:
read(size=-1)
:读取指定字节数(默认读取全部)。readline()
:读取一行。readlines()
:读取所有行并返回列表。
写入方法:
write(string)
:写入字符串(文本模式)或字节(二进制模式)。writelines(lines)
:写入多行(不自动添加换行符)。
其他方法:
close()
:关闭文件(使用with
语句时会自动调用)。tell()
:返回当前文件指针位置。seek(offset, whence=0)
:移动文件指针(whence=0
表示文件开头,1
表示当前位置,2
表示文件末尾)。
注意事项
资源管理:
推荐使用with
语句管理文件,避免手动调用close()
:python
运行
with open('file.txt', 'r') as f:# 文件在缩进块内保持打开状态data = f.read() # 离开 with 块后,文件自动关闭
编码问题:
处理文本文件时,建议显式指定encoding
参数,避免因系统编码不同导致的错误。二进制与文本模式:
- 读取非文本文件(如图片、PDF)必须使用二进制模式(
'rb'
、'wb'
)。 - 文本模式会自动处理换行符和编码转换。
- 读取非文本文件(如图片、PDF)必须使用二进制模式(
异常处理:
文件操作可能抛出FileNotFoundError
、PermissionError
等异常,建议使用try-except
捕获:python
运行
try:with open('nonexistent.txt', 'r') as f:content = f.read() except FileNotFoundError:print("文件不存在!")
通过灵活组合 open()
的参数和文件对象的方法,可以满足各种文件操作需求。
2 **kwargs
参数语法
在 Python 里,**kwargs
是一种特殊的参数语法,其作用是在函数定义时接收任意数量的关键字参数。
下面详细剖析它的含义和用法:
核心概念
**
这个符号是解包操作符,它能把字典解包为独立的关键字参数。kwargs
是一个常见的命名惯例,全称为 "keyword arguments",不过你也可以使用其他合法的变量名,像**args_dict
这样。- 它只能在函数定义的参数列表中使用,而且必须放在参数列表的末尾。
主要作用
- 接收不定数量的关键字参数
python
运行
def example(**kwargs):print(kwargs) # 会把所有关键字参数收集到一个字典中example(a=1, b=2) # 输出:{'a': 1, 'b': 2}
- 实现灵活的函数调用
python
运行
def greet(name, **info):print(f"你好,{name}")for key, value in info.items():print(f"{key}: {value}")greet("小明", 年龄=20, 城市="北京") # 输出: # 你好,小明 # 年龄: 20 # 城市: 北京
- 传递参数给其他函数
python
运行
def wrapper(**kwargs):# 把所有参数传递给另一个函数inner_function(**kwargs)
与 *args
的差异
*args
(单星号)用于收集不定数量的位置参数,会将其组合成一个元组。**kwargs
(双星号)用于收集不定数量的关键字参数,会将其组合成一个字典。
典型应用场景
- 装饰器的实现
- 类的初始化方法(例如
__init__
) - 继承时参数的传递
- 配置选项的处理
代码示例
python
运行
def my_function(a, b=10, *args, **kwargs):print(f"固定参数: a={a}, b={b}")print(f"可变位置参数: {args}")print(f"可变关键字参数: {kwargs}")# 调用示例
my_function(1, 2, 3, 4, x=5, y=6)
# 输出:
# 固定参数: a=1, b=2
# 可变位置参数: (3, 4)
# 可变关键字参数: {'x': 5, 'y': 6}
理解 **kwargs
是掌握 Python 函数高级用法的关键,它能让你编写出更加灵活、通用的代码。
我感觉就是输入的时候要x = ,赋值的这种就是**kwargs。
在函数调用时,带等号赋值的关键字参数(如 x=6, y=7
)会被 **kwargs
收集为字典;而不带等号的位置参数(如 1, 3, 4, 5
)会被 *args
收集为元组。
关键点总结:
语法对应关系:
*args
(单星号) → 收集位置参数(无赋值符号)。**kwargs
(双星号) → 收集关键字参数(带赋值符号)。
调用时的表现:
python
运行
def func(a, *args, **kwargs):print(f"a={a}, args={args}, kwargs={kwargs}")func(1, 2, 3, x=4, y=5) # 输出:a=1, args=(2, 3), kwargs={'x': 4, 'y': 5}
灵活组合示例:
python
运行
def advanced_func(a, b=10, *args, c=20, **kwargs):print(f"a={a}, b={b}, args={args}, c={c}, kwargs={kwargs}")advanced_func(1, 2, 3, 4, c=5, d=6, e=7) # 输出:a=1, b=2, args=(3, 4), c=5, kwargs={'d': 6, 'e': 7}
记忆口诀:
*args
:接收「额外的、未命名的参数」,打包成元组。**kwargs
:接收「额外的、带名字的参数」,打包成字典。
3 Python中关键字参数的语法和使用规则
在 Python 中,关键字参数(Keyword Arguments)是函数调用时通过参数名明确指定值的参数传递方式。它与位置参数(按顺序传递)共同构成了 Python 函数调用的核心语法。下面详细介绍其语法和使用规则:
一、关键字参数的基本语法
1. 函数定义时的参数类型
在函数定义中,参数可以分为以下几类:
python
运行
def func(positional, default=value, *args, **kwargs):pass
- 位置参数(Positional Parameters):必须按顺序传递的参数。
- 默认参数(Default Parameters):带有默认值的参数,调用时可省略。
- 可变位置参数(
*args
):收集额外的位置参数,打包为元组。 - 可变关键字参数(
**kwargs
):收集额外的关键字参数,打包为字典。
2. 函数调用时的关键字参数
在调用函数时,使用 参数名=值
的形式传递参数:
python
运行
def greet(name, age):print(f"你好,{name},年龄:{age}")# 使用关键字参数调用
greet(name="Alice", age=30) # 输出:你好,Alice,年龄:30
二、关键字参数的使用规则
1. 位置参数 vs 关键字参数
- 位置参数必须按定义的顺序传递,且数量必须匹配。
- 关键字参数可以按任意顺序传递,但必须明确指定参数名。
- 混合使用时,关键字参数必须放在位置参数之后:
python
运行
# 合法:位置参数在前,关键字参数在后 greet("Bob", age=25)# 非法:关键字参数不能穿插在位置参数中间 # greet(name="Charlie", 20) # 报错!
2. 默认参数的覆盖
默认参数在调用时可省略,也可用关键字参数覆盖:
python
运行
def calc(a, b=10):return a + bprint(calc(5)) # 使用默认值:5 + 10 = 15
print(calc(5, b=20)) # 覆盖默认值:5 + 20 = 25
3. 可变参数的收集
*args
收集所有未匹配的位置参数:python
运行
def func(a, *args):print(f"a={a}, args={args}")func(1, 2, 3) # 输出:a=1, args=(2, 3)
**kwargs
收集所有未匹配的关键字参数:python
运行
def func(a, **kwargs):print(f"a={a}, kwargs={kwargs}")func(1, b=2, c=3) # 输出:a=1, kwargs={'b': 2, 'c': 3}
4. 强制关键字参数(Python 3+)
使用 *
作为分隔符,要求其后的参数必须用关键字传递:
python
运行
def func(a, *, b): # b 必须用关键字传递print(a, b)func(1, b=2) # 合法
# func(1, 2) # 报错:b 必须用关键字传递
5. 参数解包(Unpacking)
使用 *
解包列表 / 元组为位置参数,**
解包字典为关键字参数:
python
运行
def greet(name, age):print(f"{name},年龄:{age}")args = ["Alice", 30]
greet(*args) # 等价于:greet("Alice", 30)kwargs = {"name": "Bob", "age": 25}
greet(**kwargs) # 等价于:greet(name="Bob", age=25)
三、常见应用场景
提高代码可读性:
python
运行
# 显式指定参数名,避免位置混淆 pandas.read_csv("data.csv", header=0, sep=",", na_values=["nan"])
函数重载模拟:
python
运行
def draw_shape(type, **options):if type == "circle":radius = options.get("radius", 1)print(f"画圆,半径:{radius}")elif type == "rectangle":width = options.get("width", 1)height = options.get("height", 1)print(f"画矩形,宽:{width},高:{height}")
装饰器:
python
运行
def log_decorator(func):def wrapper(*args, **kwargs):print(f"调用函数:{func.__name__},参数:{args}, {kwargs}")return func(*args, **kwargs)return wrapper
四、注意事项
参数名必须匹配:
python
运行
def func(x):pass# func(y=1) # 报错:参数名不匹配
避免重复传递参数:
python
运行
def func(a, b):pass# func(1, a=2) # 报错:参数 'a' 重复赋值
参数顺序限制:
- 位置参数必须在关键字参数之前。
*args
必须在**kwargs
之前。
五、总结
特性 | 描述 |
---|---|
语法形式 | 函数调用时使用 参数名=值 的形式。 |
与位置参数的关系 | 可混合使用,但关键字参数必须放在位置参数之后。 |
默认参数 | 可用关键字参数覆盖默认值。 |
可变关键字参数 (**kwargs ) | 收集所有未匹配的关键字参数,打包为字典。 |
强制关键字参数 | 使用 * 分隔符,要求其后的参数必须用关键字传递。 |
参数解包 | 使用 * 和 ** 解包容器类型为参数。 |
4 形如def fun(a,*,b)的关键字参数
执行下列程序,输出结果为()def fun(a,*,b):print(b)
fun(1,2,3,4)A [2,3,4]
B [3,4]
C 报错
D 4正确答案:C
执行这段代码会报错,错误信息类似于:
TypeError: fun() takes 1 positional argument but 4 were given
错误原因分析
函数定义的参数结构:
python
运行
def fun(a, *, b):print(b)
a
是位置参数,必须通过位置传递。*
是强制关键字参数分隔符,表示其后的参数(如b
)必须通过关键字形式传递(即b=值
)。!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!b
是强制关键字参数,调用时必须显式指定b=
,否则会报错。
函数调用的问题:
python
运行
fun(1, 2, 3, 4)
- 函数仅接受 1 个位置参数(即
a
),但调用时传递了 4 个位置参数(1, 2, 3, 4
)。 - 由于
b
是强制关键字参数,不能通过位置传递,因此会触发参数数量不匹配的错误。
- 函数仅接受 1 个位置参数(即
正确调用方式
要正确调用该函数,必须:
- 为
a
传递一个位置参数。 - 为
b
传递一个关键字参数。
例如:
python
运行
fun(1, b=2) # 输出:2
常见误区
- 误以为
*
是可变参数:在函数定义中,*
本身不是参数,而是强制关键字参数的标志。 - 混淆
*args
和*
:*args
用于收集额外的位置参数(打包为元组)。*
仅用于强制后续参数必须用关键字传递。
总结
该程序会因参数数量不匹配和未使用关键字参数传递 b
而报错。正确的输出结果无法得到,需修改调用方式。
5 比大小
下列表达式的值为True的是( )
A 5+4j > 2-3j
B 3>2>2
C (3,2)> (1,'b')
D ’abc’ > ‘xyz’正确答案:C
选项 A:5 + 4j > 2 - 3j
- 规则:Python 中复数不能比较大小(不支持
>
,<
,>=
,<=
操作)。 - 结果:执行时会直接报错(
TypeError: '>' not supported between instances of 'complex' and 'complex'
),因此该表达式不成立。
选项 B:3 > 2 > 2
- 规则:连续比较会拆解为逻辑与(
and
)运算,即3 > 2 and 2 > 2
。- 第一步:
3 > 2
结果为True
。 - 第二步:
2 > 2
结果为False
。 - 最终:
True and False
结果为False
。
- 第一步:
- 结论:表达式值为
False
。
选项 C:(3, 2) > (1, 'b')
- 规则:元组比较遵循逐元素比较:
- 先比较第一个元素:
3 > 1
,结果为True
。 - 由于第一个元素已能确定大小,后续元素不再比较。
- 先比较第一个元素:
- 结论:整个表达式结果为
True
。
选项 D:'abc' > 'xyz'
- 规则:字符串比较基于字符的 ASCII 码值(逐字符对比):
- 第一个字符:
'a'
的 ASCII 码为 97,'x'
的 ASCII 码为 120。 - 因
97 < 120
,即'a' < 'x'
,直接得出整个字符串比较结果。
- 第一个字符:
- 结论:表达式值为
False
。
总结
只有选项 C 的表达式值为 True
,因此正确答案是 C。