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次方
// 取整除 - 往小的方向取整数
>>> 9//2
4
>>> -9//2
-5

精度丢失问题,浮点数直接使用运算符计算会有精度丢失问题

>>> 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() 两次:

if (n := len(a)) > 10:
    print(f"List is too long ({n} elements, expected <= 10)")
# 传统写法
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

 

posted @ 2025-01-06 10:05  星光闪闪  阅读(67)  评论(0)    收藏  举报