python总结-语法
基础语法
Python中严格区分大小写
行与缩进
每一行就是一条语句,每条语句以换行结束
Python中每一行语句不要过长(规范中建议每行不要超过80个字符)
一条语句可以分多行编写,多行编写时语句后边以"\"结尾
print("Hello, everyone!\n \
I am so glad to introduce Python to you!")
total = item_one + \
item_two + \
item_three
在 [], {}, 或 () 中的多行语句,不需要使用反斜杠 \,例如:
total = ['item_one', 'item_two', 'item_three',
'item_four', 'item_five']
Python是缩进严格的语言,以缩进来表示代码块,所以在Python中不要随便写缩进
a = True
if a:
print("True")
else:
print("False")
缩进的空格数是可变的,但是同一个代码块的语句必须包含相同的缩进空格数。
if True:
print ("Answer")
print ("True")
else:
print ("Answer")
print ("False") # 缩进不一致,会导致运行错误
空行
函数之间或类的方法之间用空行分隔,表示一段新的代码的开始。类和函数入口之间也用一行空行分隔,以突出函数入口的开始。
空行与代码缩进不同,空行并不是 Python 语法的一部分。书写时不插入空行,Python 解释器运行也不会出错。但是空行的作用在于分隔两段不同功能或含义的代码,便于日后代码的维护或重构。
同一行显示多条语句
可以在同一行中使用多条语句,语句之间使用分号 ; 分割
import sys; x = 'runoob'; sys.stdout.write(x + '\n')
注释
#来表示单行注释,"#"后的内容都属于注释,注释的内容将会被解释器所忽略
python 中多行注释使用三个单引号(''')或三个双引号(""")。多行注释不能嵌套。
# 第一个单行注释
'''
这是多行注释,使用单引号。
这是多行注释,使用单引号。
这是多行注释,使用单引号。
'''
"""
这是多行注释,使用双引号。
这是多行注释,使用双引号。
这是多行注释,使用双引号。
"""
标识符
- 在Python里, 标识符: 由字母、数字、下划线组成,但不能以数字开头
- 标识符是区分大小写的
- 特殊标识符:
- 以下划线开头的标识符是有特殊意义的。以单下划线开头 _foo 的代表不能直接访问的类属性,需通过类提供的接口进行访问,不能用 from xxx import * 而导入;
- 以双下划线开头的 __foo 代表类的私有成员;以双下划线开头和结尾的 __foo__ 代表 Python 里特殊方法专用的标识,如 __init__() 代表类的构造函数。
- python保留字: 保留字即关键字,我们不能把它们用作任何标识符名称。Python 的标准库提供了一个 keyword 模块,可以输出当前版本的所有关键字:
>>> import keyword
>>> keyword.kwlist
['False', 'None', 'True', 'and', 'as', 'assert', 'break', 'class', 'continue',
'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global',
'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'if',
'return','try', 'while', 'with', 'yield']
变量
Python 中的变量不需要声明。每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建。
在 Python 中,变量就是变量,它没有类型,我们所说的"类型"是变量所指的内存中对象的类型。
等号(=)用来给变量赋值。
等号(=)运算符左边是一个变量名,等号(=)运算符右边是存储在变量中的值。例如:
counter = 100 # 整型变量
miles = 1000.0 # 浮点型变量
name = "demo" # 字符串
print(counter)
print(miles)
print(name)
允许你同时为多个变量赋值
a = b = c = 1
以上实例,创建一个整型对象,值为1,三个变量被分配到相同的内存空间上。
也可以为多个对象指定多个变量。例如:
a, b, c = 1, 2, "demo"
两个整型对象 1 和 2 的分配给变量 a 和 b,字符串对象 "demo" 分配给变量 c。
特殊变量
__name__:表示当前模块的名称,当模块被直接运行时,__name__ 的值为 "__main__"。当模块被导入时,__name__ 的值为模块的名称。
__file__:存储当前模块的文件路径。
__doc__:存储模块、类、函数或方法的文档字符串(docstring)。使用场景:访问对象的文档说明,便于生成帮助文档或调试。
__dict__:存储对象的属性和它们的值,以字典形式表示。
class Person:
def __init__(self, name):
self.name = name
person = Person("Alice")
print(person.__dict__) # 输出: {'name': 'Alice'}
__slots__:限制类的实例能添加的属性范围,节省内存。使用场景:优化性能,防止动态添加属性。
class P:
__slots__ = ("name", "age") # 限制实例只能有 name 和 age 属性
p = P()
p.name = "Alice" # 合法
p.age = 25 # 合法
# p.gender = "female" # 非法,会抛出 AttributeError
__init__:类的构造函数,在创建实例时调用,用于初始化对象。
class Person:
def __init__(self, name):
self.name = name
p = Person("Alice") # 调用 __init__ 方法
__str__ 和 __repr__:
__str__:返回对象的用户友好字符串表示形式,用于 print()。
__repr__:返回对象的开发者友好字符串表示形式,用于调试。
class Person:
def __init__(self, name):
self.name = name
def __str__(self):
return f"Person(name={self.name})"
def __repr__(self):
return f"Person('{self.name}')"
p = Person("Alice")
print(str(p)) # 输出: Person(name=Alice)
print(repr(p)) # 输出: Person('Alice')
__call__:使对象可以像函数一样被调用。
class Adder:
def __call__(self, x, y):
return x + y
adder = Adder()
print(adder(2, 3)) # 输出: 5
__enter__ 和 __exit__:实现上下文管理器,用于 with 语句。使用场景:管理资源(如文件、锁)的获取和释放。
class FileManager:
def __init__(self, filename):
self.filename = filename
def __enter__(self):
self.file = open(self.filename, 'r')
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
self.file.close()
with FileManager('example.txt') as f:
print(f.read())
__iter__ 和 __next__:实现迭代器协议,使对象可以被迭代。使用场景:自定义迭代逻辑。
class Fibonacci:
def __init__(self, max):
self.max = max
self.current = 0
self.a, self.b = 0, 1
def __iter__(self):
return self
def __next__(self):
if self.current < self.max:
self.a, self.b = self.b, self.a + self.b
self.current += 1
return self.a
raise StopIteration
for num in Fibonacci(5):
print(num) # 输出: 1, 2, 3, 5, 8
import 与 from...import
python 用 import 或者 from...import 来导入相应的模块。
将整个模块(somemodule)导入,格式为: import somemodule
从某个模块中导入某个函数,格式为: from somemodule import somefunction
从某个模块中导入多个函数,格式为: from somemodule import firstfunc, secondfunc, thirdfunc
将某个模块中的全部函数导入,格式为: from somemodule import *
pass关键字
它是Python的保留关键字,用于需要语法结构但逻辑上“什么都不做”的场景(如占位符、空函数体、条件分支等)。
# 空函数占位
def my_function():
pass # 函数尚未实现时的占位符
# 空类占位
class MyClass:
pass # 类尚未实现时的占位符
# 条件分支占位
if condition:
pass # 条件满足但暂不执行操作
else:
print("Condition not met")
# 遍历列表时忽略某些元素(不执行操作)
for item in [1, 2, 3, 4]:
if item == 2:
pass # 暂时跳过2的处理
else:
print(item) # 输出1,3,4
# 无限循环占位(等待中断)
while True:
pass # 等待用户中断(如Ctrl+C)
try:
risky_operation()
except FileNotFoundError:
pass # 忽略文件未找到的错误,继续执行
except Exception as e:
raise # 其他异常正常抛出
运算符
算数运算符
| 运算符 | 描述 | 实例 |
|---|---|---|
| + | 加 - 两个对象相加 | a + b 输出结果 31 |
| - | 减 - 得到负数或是一个数减去另一个数 | a - b 输出结果 -11 |
| * | 乘 - 两个数相乘或是返回一个被重复若干次的字符串 | a * b 输出结果 210 |
| / | 除 - x 除以 y | b / a 输出结果 2.1 |
| % | 取模 - 返回除法的余数 | b % a 输出结果 1 |
| ** | 幂 - 返回x的y次幂 | a**b 为10的21次方 |
| // | 取整除 - 往小的方向取整数 |
|
精度丢失问题,浮点数直接使用运算符计算会有精度丢失问题
>>> a=0.1
>>> b=0.2
>>> print(a+b)
0.30000000000000004
>>>
解决精度丢失问题,要引入decimal模块
比较运算符
| 运算符 | 描述 | 实例 |
|---|---|---|
| == | 等于 - 比较对象是否相等 | (a == b) 返回 False。 |
| != | 不等于 - 比较两个对象是否不相等 | (a != b) 返回 True。 |
| > | 大于 - 返回x是否大于y | (a > b) 返回 False。 |
| < | 小于 - 返回x是否小于y。所有比较运算符返回1表示真,返回0表示假。这分别与特殊的变量True和False等价。注意,这些变量名的大写。 | (a < b) 返回 True。 |
| >= | 大于等于 - 返回x是否大于等于y。 | (a >= b) 返回 False。 |
| <= | 小于等于 - 返回x是否小于等于y。 | (a <= b) 返回 True。 |
赋值运算符
| 运算符 | 描述 | 实例 |
|---|---|---|
| = | 简单的赋值运算符 | c = a + b 将 a + b 的运算结果赋值为 c |
| += | 加法赋值运算符 | c += a 等效于 c = c + a |
| -= | 减法赋值运算符 | c -= a 等效于 c = c - a |
| *= | 乘法赋值运算符 | c *= a 等效于 c = c * a |
| /= | 除法赋值运算符 | c /= a 等效于 c = c / a |
| %= | 取模赋值运算符 | c %= a 等效于 c = c % a |
| **= | 幂赋值运算符 | c **= a 等效于 c = c ** a |
| //= | 取整除赋值运算符 | c //= a 等效于 c = c // a |
| := | 海象运算符,这个运算符的主要目的是在表达式中同时进行赋值和返回赋值的值。Python3.8 版本新增运算符。 |
在这个示例中,赋值表达式可以避免调用 len() 两次:
|
# 传统写法
n = 10
if n > 5:
print(n)
# 使用海象运算符
if (n := 10) > 5:
print(n)
位运算符
| 运算符 | 描述 | 实例 |
|---|---|---|
| & | 按位与运算符:参与运算的两个值,如果两个相应位都为1,则该位的结果为1,否则为0 | (a & b) 输出结果 12 ,二进制解释: 0000 1100 |
| | | 按位或运算符:只要对应的二个二进位有一个为1时,结果位就为1。 | (a | b) 输出结果 61 ,二进制解释: 0011 1101 |
| ^ | 按位异或运算符:当两对应的二进位相异时,结果为1 | (a ^ b) 输出结果 49 ,二进制解释: 0011 0001 |
| ~ | 按位取反运算符:对数据的每个二进制位取反,即把1变为0,把0变为1。~x 类似于 -x-1 | (~a ) 输出结果 -61 ,二进制解释: 1100 0011, 在一个有符号二进制数的补码形式。 |
| << | 左移动运算符:运算数的各二进位全部左移若干位,由"<<"右边的数指定移动的位数,高位丢弃,低位补0。 | a << 2 输出结果 240 ,二进制解释: 1111 0000 |
| >> | 右移动运算符:把">>"左边的运算数的各二进位全部右移若干位,">>"右边的数指定移动的位数 | a >> 2 输出结果 15 ,二进制解释: 0000 1111 |
#!/usr/bin/python3
a = 60 # 60 = 0011 1100
b = 13 # 13 = 0000 1101
c = 0
c = a & b # 12 = 0000 1100
print ("1 - c 的值为:", c)
c = a | b # 61 = 0011 1101
print ("2 - c 的值为:", c)
c = a ^ b # 49 = 0011 0001
print ("3 - c 的值为:", c)
c = ~a # -61 = 1100 0011
print ("4 - c 的值为:", c)
c = a << 2 # 240 = 1111 0000
print ("5 - c 的值为:", c)
c = a >> 2 # 15 = 0000 1111
print ("6 - c 的值为:", c)
逻辑运算符
假设变量 a 为 10, b为 20:
| 运算符 | 逻辑表达式 | 描述 | 实例 |
|---|---|---|---|
| and | x and y | 布尔"与" - 如果 x 为 False,x and y 返回 x 的值,否则返回 y 的计算值。 | (a and b) 返回 20。 |
| or | x or y | 布尔"或" - 如果 x 是 True,它返回 x 的值,否则它返回 y 的计算值。 | (a or b) 返回 10。 |
| not | not x | 布尔"非" - 如果 x 为 True,返回 False 。如果 x 为 False,它返回 True。 | not(a and b) 返回 False |
>>> True and True
True
>>> False and False
False
>>> True and False
False
>>> False and True
False
>>> 2>1 and 3>2
True
>>> 2<1 and 3>2
False
>>> 2>1 and 3<2
False
>>> 10 and 20
20
>>> -1 and 1
1
>>> 0 and 1
0
>>
>>> 2>1 or 3>2
True
>>> 2>1 or 3<2
True
>>> 2<1 or 3>2
True
>>> 2<1 or 3<2
False
>>> 10 or 20
10
>>> -1 or 1
-1
>>> 0 or 1
1
>>> not 2>1
False
>>> not 2<1
True
>>> not 0
True
>>> not 1
False
成员运算符
| 运算符 | 描述 | 实例 |
|---|---|---|
| in | 如果在指定的序列中找到值返回 True,否则返回 False。 | x 在 y 序列中 , 如果 x 在 y 序列中返回 True。 |
| not in | 如果在指定的序列中没有找到值返回 True,否则返回 False。 | x 不在 y 序列中 , 如果 x 不在 y 序列中返回 True。 |
#!/usr/bin/python3
a = 10
b = 20
list = [1, 2, 3, 4, 5 ]
if ( a in list ):
print ("1 - 变量 a 在给定的列表中 list 中")
else:
print ("1 - 变量 a 不在给定的列表中 list 中")
if ( b not in list ):
print ("2 - 变量 b 不在给定的列表中 list 中")
else:
print ("2 - 变量 b 在给定的列表中 list 中")
身份运算符
身份运算符用于比较两个对象的存储单元
| is | is 是判断两个标识符是不是引用自一个对象 | x is y, 类似 id(x) == id(y) , 如果引用的是同一个对象则返回 True,否则返回 False |
| is not | is not 是判断两个标识符是不是引用自不同对象 | x is not y , 类似 id(x) != id(y)。如果引用的不是同一个对象则返回结果 True,否则返回 False。 |
id() 函数用于获取对象内存地址。
is 与 == 区别:
is 用于判断两个变量引用对象是否为同一个, == 用于判断引用变量的值是否相等。
a = [1, 2, 3]
b = [1, 2, 3]
print(a is b) #False is 比较的是两者的内存地址(id())
print(id(a)) #2850269774400
print(id(b)) #2850269774208
a = [1, 2, 3]
b = [1, 2, 3]
print(a == b) # True : 比较,它比较的是值
三目运算符
true_expression if condition else false_expression
condition是判断条件,true_expression 和 false_expression 是两个表达式,用 if…else… 连接。如果 condition 成立(结果为真),就执行 true_expression,并把 true_expression 的结果作为整个表达式的结果。如果 condition 不成立(结果为假),就执行 false_expression,并把 false_expression 的结果作为整个表达式的结果。
a = 1
b = 2
if a+b>3:
print(a+b)
else:
print(b-a) #得1
改成三目运算符
a = 1
b = 3
print(a+b if a+b > 3 else b-a) #得4
可以嵌套
num = int(input('请输入数字:'))
print('负数') if str(num)[0] == '-' else print('大于等于100') if num >= 100 else print('小于100的正数')
函数
函数是可重用的代码块,用于封装特定逻辑并接受输入(参数)、执行操作后返回结果。支持代码复用、逻辑解耦和抽象。
语法:
def 函数名(参数列表):
"""文档字符串(可选,用于说明函数功能)"""
函数体(执行逻辑)
return 返回值 # 可选,无 return 则返回 None
def add(a, b):
return a + b
result = add(3, 5) # 调用,result=8
Python 采用对象引用传递:
- 不可变对象(如数字、字符串、元组):函数内修改不影响原对象。
- 可变对象(如列表、字典):函数内修改会影响原对象(直接修改内容)。
返回值
- 使用 return 返回值,可返回单个值或元组(多个值自动封装为元组)。
- 无 return 时,函数返回 None。
匿名函数:lambda 参数列表: 表达式
# 将 lambda 作为参数传递
numbers = [1, 2, 3]
squared = list(map(lambda x: x**2, numbers)) # [1, 4, 9]
递归:函数调用自身,需设置终止条件。
def factorial(n):
if n == 0:
return 1
return n * factorial(n-1)
类型提示与注解(Python 3.5+):
使用 : type 声明参数类型,-> type 声明返回值类型。
配合 typing 模块支持复杂类型(如 List[int], Tuple[str, int])。
from typing import List
def sum_list(numbers: List[int]) -> int:
return sum(numbers)
常用函数
输入输出函数
input()的小括号中放入的是,提示信息,用来在获取数据之前给用户的一个简单提示
input()在从键盘获取了数据以后,会存放到等号右边的变量中
input()会把用户输入的任何值都作为字符串来对待
str = input("请输入:");
print ("你输入的内容是: ", str)
print 默认输出是换行的,如果要实现不换行需要在变量末尾加上 end=""
x="a"
y="b"
# 换行输出
print( x )
print( y )
print('---------')
# 不换行输出
print( x, end=" " )
print( y, end=" " )
print()
# 同时输出多个变量
print(x,y)
format格式化函数
字符串格式化的功能
# 不设置指定位置,按默认顺序
template = "name: {}, age: {}"
print(template.format("John","18"))
# 设置指定位置
template = "name: {0}, age: {1} \nWelcome, {0}"
print(template.format("John", "18"))
# 设置指定参数名
template = "name: {name}, age: {age}"
print(template.format(name="John", age="18"))
# 通过字典设置参数
template = "name: {name}, age: {age}"
john = {"name": "John", "age":"18"}
print(template.format(**john)) # **表示接收的参数作为字典来处理,*表示接收的参数作为元组来处理
# 通过列表索引设置参数
my_list = ['John', '18']
template = "name: {0[0]}, age: {0[1]}" # 第一个数字0,用于表示format参数,可以传入多个列表参数,中括号中表示数组下标
print(template.format(my_list))
# 练习:尝试混用上述方式~
# 数字格式化
print("PI: {:.2f}".format(3.1415926))
| 数字 | 格式 | 输出 | 描述 |
|---|---|---|---|
| 3.1415926 | {:.2f} | 3.14 | 保留小数点后两位 |
| 3.1415926 | {:+.2f} | +3.14 | 带符号保留小数点后两位 |
| -1 | {:+.2f} | -1.00 | 带符号保留小数点后两位 |
| 2.71828 | {:.0f} | 3 | 不带小数 |
| 5 | {:0>2d} | 05 | 数字补零 (填充左边, 宽度为2) |
| 5 | {:x<4d} | 5xxx | 数字补x (填充右边, 宽度为4) |
| 10 | {:x<4d} | 10xx | 数字补x (填充右边, 宽度为4) |
| 1000000 | {:,} | 1,000,000 | 以逗号分隔的数字格式 |
| 0.25 | {:.2%} | 25.00% | 百分比格式 |
| 1000000000 | {:.2e} | 1.00e+09 | 指数记法 |
| 13 | {:10d} | 13 | 右对齐 (默认, 宽度为10) |
| 13 | {:<10d} | 13 | 左对齐 (宽度为10) |
| 13 | {:^10d} | 13 | 中间对齐 (宽度为10) |
| 11 | '{:b}'.format(11) '{:d}'.format(11) '{:o}'.format(11) '{:x}'.format(11) '{:#x}'.format(11) '{:#X}'.format(11) |
1011 11 13 b 0xb 0XB |
进制 |
空格使用
- 在二元运算符两边各空一格,比如赋值(=)、比较(==, <, >, !=, <>, <=, >=, in, not in, is, is not), 布尔(and, or, not),算术操作符两边的空格可灵活使用,但两侧务必要保持一致
- 不要在逗号、分号、冒号前面加空格,但应该在它们后面加(除非在行尾)
- 函数的参数列表中,逗号之后要有空格
- 函数的参数列表中,默认值等号两边不要添加空格
- 左括号之后,右括号之前不要加添加空格
- 参数列表, 索引或切片的左括号前不应加空格
- 当'='用于指示关键字参数或默认参数值时,不要在其两侧使用空格
引号说明
One('hello world?')
Tow("my site is vitian.vip") # 单引号和双引号字符串是相同的。
Three('"hell!" vitian.') # 在同一个文件中,保持使用字符串引号的一致性。在字符串内可以使用另外一种引号,以避免在字符串中使用。
导入
导入模块和包是使用内置的 import 语句来完成的。
导入模块
import module_name
导入模块中的特定部分
from module_name import specific_name
导入模块中的所有内容(不推荐,因为可能会导致命名冲突)
from module_name import *
导入模块并为其指定别名
import module_name as alias
import math as m
print(m.sqrt(16)) # 输出: 4.0
导入应该放在文件顶部,位于模块注释和文档字符串之后,模块全局变量和常量之前。导入应该按照从最通用到最不通用的顺序分组:标准库导入、第三方库导入、应用程序指定导入,分组之间空一行。尽量保持模块名简单,以无需分开单词最佳(不推荐在两个单词之间使用下划线)。
import os # 模块名称要短,使用小写,并避免使用特殊符号, 比如点和问号。
import numpy # 每个导入应该独占一行。
import sys
from types import StringType, ListType
异常处理
try-except块:
try:
# 可能引发异常的代码
result = 10 / 0
except ZeroDivisionError as e:
print(f"除零错误: {e}")
多异常捕获:
except (ValueError, TypeError) as e:
print(f"值或类型错误: {e}")
else子句:
当try块无异常时执行(常用于无异常时的后续操作)
try:
open("file.txt")
except FileNotFoundError:
pass
else:
print("文件成功打开")
finally块:
无论是否异常均执行(用于资源清理,如关闭文件)
finally:
file.close()
内置异常类型:
Python内置异常继承自BaseException,核心分支为Exception:
常见类型:
- ZeroDivisionError:除零错误
- FileNotFoundError:文件未找到
- ValueError:无效值(如int("a"))
- TypeError:类型不匹配(如"1" + 1)
- IndexError:列表越界访问
- KeyError:字典键不存在
- ImportError:模块导入失败
系统退出类(继承自SystemExit):如SystemExit(sys.exit()触发)、KeyboardInterrupt(Ctrl+C)
自定义异常:
需继承Exception或其子类,通过__init__和__str__定制信息:
class NetworkError(Exception):
"""自定义网络异常"""
def __init__(self, port, message="连接失败"):
self.port = port
self.message = f"{message} on port {port}"
super().__init__(self.message)
def __str__(self):
return self.message
raise NetworkError(8080)
异常传播与链式异常
未捕获的异常沿调用栈向上传递,直至顶层或被捕获。
链式异常:使用raise ... from ...关联原始异常:
try:
1 / 0
except ZeroDivisionError as e:
raise ValueError("计算失败") from e
输出时显示两个异常的因果关系。
traceback分析:
使用traceback模块获取异常详细堆栈:
import traceback
try:
1 / 0
except:
traceback.print_exc() # 打印堆栈到标准错误
文件相关
with语句:
- with语句是一种上下文管理协议的实现,主要用于简化资源管理(如文件、锁、网络连接等)和确保代码块执行后资源能被正确释放,即使处理过程中发生异常也能保证清理操作。它的核心设计理念是“资源在使用后自动释放”,避免手动管理资源可能导致的泄露或错误。
- with语句依赖实现了__enter__和__exit__方法的上下文管理器
- __enter__:进入with块时自动调用,用于初始化资源(如打开文件、获取锁),并返回一个对象(通过as子句绑定到变量)。
__exit__:退出with块时自动调用,用于清理资源(如关闭文件、释放锁)。即使代码块中发生异常,__exit__也会被执行,确保资源安全释放。 -
with 上下文管理器 [as 变量]: 代码块 - as 变量可选,用于接收__enter__返回的对象(如文件对象)
- 支持嵌套多个上下文管理器(用逗号分隔)或使用多个with语句。
文件操作:
# 传统方式(需手动关闭)
file = open("test.txt", "r")
try:
content = file.read()
finally:
file.close()
# with方式(自动关闭)
with open("test.txt", "r") as file:
content = file.read() # 退出with块后,文件自动关闭
线程锁(避免死锁):
from threading import Lock
lock = Lock()
with lock: # 自动获取和释放锁
# 临界区代码(线程安全)
print("Critical section")
数据库连接(防止泄露):
import sqlite3
with sqlite3.connect("mydb.db") as conn:
cursor = conn.cursor()
cursor.execute("SELECT * FROM users")
# 退出with块后,连接自动关闭
临时修改全局状态(如十进制精度):
from decimal import Decimal, localcontext
with localcontext() as ctx:
ctx.prec = 6 # 临时设置精度为6位
result = Decimal("1") / Decimal("7")
print(result) # 输出:0.142857
# 退出后恢复原始精度
多上下文管理器处理:
with open("file1.txt") as f1, open("file2.txt") as f2:
print(f1.read(), f2.read())
open函数
open()函数是文件操作的核心工具,用于打开文件并返回一个文件对象,支持对文件进行读、写、追加等操作。
基本语法:
file_obj = open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
file(必填)
- 文件路径(字符串),支持相对路径或绝对路径。
- 若文件不存在,某些模式(如'w')会新建文件;若路径为目录,可能引发IsADirectoryError。
mode(默认'r'):
决定文件的打开方式,常见模式组合:
| 模式 | 含义 | 行为 |
|---|---|---|
'r' |
读取(文本) | 文件必须存在,从文件头读取 |
'w' |
写入(文本) | 覆盖文件(若存在),否则新建 |
'a' |
追加(文本) | 文件不存在则新建,写入位置在末尾 |
'x' |
独占创建 | 文件存在则抛出FileExistsError |
'b' |
二进制模式 | 与上述模式组合(如'rb'、'wb'),处理非文本数据(如图片、视频) |
'+' |
更新模式 | 允许读写(如'r+'、'w+'),需注意指针位置 |
# 读取文本文件
with open("data.txt", "r", encoding="utf-8") as f:
content = f.read()
# 二进制写入
with open("image.png", "wb") as f:
f.write(b"\x89PNG\r\n") # 写入PNG文件头
二进制 vs 文本模式
- 处理非文本数据(如图片、压缩文件)时用二进制模式('rb'、'wb'),避免编码转换。
- 文本模式(如'r')会自动处理换行符和编码,适合文本文件。
encoding(文本模式重要参数)
- 指定字符编码(如"utf-8"、"gbk"),默认使用系统编码(可能引发跨平台问题)。
- 若文件编码与指定编码不匹配,可通过errors参数处理(如errors="ignore"跳过错误,errors="replace"替换非法字符)。
newline(文本模式控制换行):控制换行符的处理方式:
- None:通用换行模式(\r\n、\r、\n统一转为\n),写入时使用系统默认换行符。
- ""(空字符串):禁用换行转换,适合二进制数据或跨平台一致性。
- "\n"、"\r"、"\r\n":强制指定换行符。
buffering(缓冲控制)控制读写缓冲策略:
- 0:无缓冲(直接写入磁盘,性能低,仅二进制模式有效)。
- 1:行缓冲(文本模式,遇到换行符\n时刷新缓冲区)。
- >1:指定缓冲区大小(字节),默认由系统决定(通常为4096或8192字节)。
处理大文件
避免一次性读取大文件(如read()),改用迭代逐行处理:
with open("huge_file.txt") as f:
for line in f: # 高效迭代,逐行读取
process(line)
异常处理
try:
with open("missing.txt") as f:
data = f.read()
except FileNotFoundError:
print("文件不存在!")
tempfile模块
tempfile 是 Python 标准库中用于创建临时文件和目录的跨平台工具模块,其核心功能是自动生成唯一命名的临时资源,并在程序结束或显式释放时自动清理,避免资源泄漏和命名冲突。
tempfile 模块本身是线程安全的,但需确保多线程环境下对同一临时文件的访问同步。
特点
跨平台兼容性:
- 支持 Windows、Linux、macOS 等系统,自动选择系统默认的临时目录(如 Windows 的 %TEMP%,Linux 的 /tmp)。
- 通过 gettempdir() 可获取当前系统的临时目录路径。
唯一命名与安全性:
- 文件名由随机字符、进程 ID 和时间戳生成,避免冲突。
- 默认设置严格权限(仅当前用户可访问),防止未授权访问。
自动清理机制:
- 高级接口(如 TemporaryFile、NamedTemporaryFile)支持通过 with 语句或显式调用 close() 自动删除资源。
- 低级接口(如 mkstemp)需手动清理,但提供更灵活的控制。
无名临时文件:
TemporaryFile(mode='w+b', ...)
(无文件系统可见名称),适用于仅需内存映射或进程内使用的场景
with tempfile.TemporaryFile() as f:
f.write(b"Temporary data") # 写入二进制数据
f.seek(0)
print(f.read()) # 输出: b'Temporary data'
# 退出with块后文件自动删除
有名临时文件
NamedTemporaryFile(mode='w+t', delete=True, ...)
可通过文件名访问,适合需要跨进程共享或持久化临时数据的场景。
- delete=True(默认):关闭时自动删除。
- suffix/prefix:指定文件后缀(如 .csv)或前缀。
with tempfile.NamedTemporaryFile(suffix=".txt", delete=False) as f:
f.write("Hello, tempfile!") # 写入文本数据
print(f"File path:", f.name) # 输出临时文件路径
# 需手动删除(若delete=False)
# os.unlink(f.name)
创建临时目录
TemporaryDirectory()
创建临时目录,返回路径字符串,支持嵌套文件管理。
with tempfile.TemporaryDirectory() as tmpdir:
print(f"Temp dir: {tmpdir}")
with open(os.path.join(tmpdir, "test.txt"), "w") as f:
f.write("Data in temp dir")
# 目录及其内容自动删除
低级函数(需手动清理)
mkstemp(suffix='', prefix='', dir=None)
返回元组 (fd, path),包含文件描述符和路径,需手动关闭文件并删除。
fd, path = tempfile.mkstemp(suffix=".log")
try:
with os.fdopen(fd, "w") as f:
f.write("Log data")
finally:
os.unlink(path) # 手动删除文件
mkdtemp(suffix='', prefix='', dir=None)
创建临时目录,返回路径字符串,需手动删除。
tmpdir = tempfile.mkdtemp()
try:
print(f"Manual temp dir: {tmpdir}")
finally:
import shutil
shutil.rmtree(tmpdir) # 递归删除目录
大文件操作
大文件操作时,结合 SpooledTemporaryFile(内存缓冲,超阈值后写入磁盘):
with tempfile.SpooledTemporaryFile(max_size=1024*1024) as f: # 1MB阈值
f.write(b"x" * 2048*1024) # 超过阈值后自动写入磁盘
传参语法
位置参数:按参数在函数定义中的顺序依次传递。
def add(a, b):
return a + b
print(add(3, 5)) # 输出 8
关键字参数:通过参数名显式传递,顺序可任意。
def greet(name, age):
print(f"{name} is {age} years old")
greet(age=25, name="Alice") # 输出 "Alice is 25 years old"
默认参数:为参数设置默认值,调用时可省略;默认参数必须定义在非默认参数之后。
def power(x, exponent=2):
return x ** exponent
print(power(3)) # 输出 9(使用默认指数 2)
print(power(3, 3)) # 输出 27
可变位置参数(*args):收集任意多个位置参数为一个元组。
def sum_all(*numbers):
return sum(numbers)
print(sum_all(1, 2, 3, 4)) # 输出 10
#当函数使用 *args 收集可变位置参数时,即使只传递一个参数,此时无需手动加逗号,因为 *args 机制会自动将多个参数封装为元组。
print(sum_all(1))
元组类型传参:
指定入参为元组类型时,如果只有一个参数后面要加上逗号,否则会提示类型错误
from typing import Tuple
def example(x: Tuple[int]):
pass
# 必须传递 (1,) 而非 (1)
example((1,))
可变关键字参数(kwargs)**:
def print_info(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
print_info(name="Bob", age=30, city="New York")
参数传递顺序规则:
严格顺序:必须按以下顺序定义参数:
普通位置参数
默认参数
可变位置参数(*args)
关键字参数(如 param=value)
可变关键字参数(**kwargs)
def complex_func(a, b=10, *args, c=20, **kwargs):
pass
仅限关键字参数:在 * 后定义的参数必须通过关键字传递。
def func(a, *, b, c=100):
print(a, b, c)
func(1, b=2) # 合法:a=1(位置),b=2(关键字)
func(1, 2, c=3) # 报错:* 后参数必须用关键字传递
参数解包:使用 * 解包序列
numbers = [1, 2, 3]
print(*numbers) # 等效于 print(1, 2, 3)
使用 ** 解包字典:
config = {"mode": "debug", "level": 2}
def setup(mode, level, timeout=10):
print(mode, level, timeout)
setup(**config, timeout=30) # 输出 debug 2 30
引用说明:https://developer.aliyun.com/article/789131

浙公网安备 33010602011771号