输入/输出(I/O)操作是任何编程语言的基础,使程序能够与文件、数据库、网络和其他外部资源进行交互。本指南探讨Python强大的I/O功能,从基本文件操作到高级数据库交互。
目录
文件I/O
基本文件操作
Python提供了多种处理文件的方式。最常用的是使用open()
函数:
# 基本文件读取
with open('example.txt', 'r') as file:
content = file.read() # 读取整个文件
# 基本文件写入
with open('output.txt', 'w') as file:
file.write('你好,世界!')
文件模式和编码
# 常用文件模式
'r' # 读取(默认)
'w' # 写入(清空文件)
'a' # 追加
'x' # 独占创建
'b' # 二进制模式
't' # 文本模式(默认)
'+' # 读写模式
# 使用编码的示例
with open('unicode.txt', 'w', encoding='utf-8') as file:
file.write('你好,世界!')
读取技术
# 读取整个文件
with open('file.txt', 'r') as file:
content = file.read()
# 逐行读取
with open('file.txt', 'r') as file:
for line in file:
print(line.strip())
# 读取固定大小的块
with open('large_file.txt', 'r') as file:
chunk = file.read(1024) # 每次读取1KB
while chunk:
process_chunk(chunk)
chunk = file.read(1024)
二进制文件
# 读取二进制文件
with open('image.png', 'rb') as file:
binary_data = file.read()
# 写入二进制文件
with open('output.bin', 'wb') as file:
file.write(bytes([0x00, 0x01, 0x02, 0x03]))
文件系统操作
import os
import shutil
# 检查文件是否存在
if os.path.exists('file.txt'):
print('文件存在')
# 目录操作
os.makedirs('new/nested/directory', exist_ok=True)
os.rmdir('empty_directory')
# 文件复制和移动
shutil.copy2('source.txt', 'destination.txt')
shutil.move('old_path.txt', 'new_path.txt')
# 列出目录内容
files = os.listdir('.')
数据库I/O
SQLite(内置)
import sqlite3
# 创建连接
conn = sqlite3.connect('example.db')
cursor = conn.cursor()
# 创建表
cursor.execute('''
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
email TEXT UNIQUE
)
''')
# 插入数据
cursor.execute('INSERT INTO users (name, email) VALUES (?, ?)',
('张三', 'zhangsan@example.com'))
conn.commit()
# 查询数据
cursor.execute('SELECT * FROM users WHERE name = ?', ('张三',))
result = cursor.fetchall()
# 使用上下文管理器
with sqlite3.connect('example.db') as conn:
cursor = conn.cursor()
cursor.execute('SELECT * FROM users')
results = cursor.fetchall()
MySQL(使用mysql-connector-python)
import mysql.connector
# 建立连接
conn = mysql.connector.connect(
host="localhost",
user="user",
password="password",
database="example_db"
)
try:
cursor = conn.cursor()
# 创建表
cursor.execute('''
CREATE TABLE IF NOT EXISTS products (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255),
price DECIMAL(10, 2)
)
''')
# 使用参数插入数据
sql = "INSERT INTO products (name, price) VALUES (%s, %s)"
values = ("产品A", 19.99)
cursor.execute(sql, values)
# 批量插入
values = [
("产品B", 29.99),
("产品C", 39.99)
]
cursor.executemany(sql, values)
conn.commit()
finally:
cursor.close()
conn.close()
PostgreSQL(使用psycopg2)
import psycopg2
from psycopg2.extras import DictCursor
# 带错误处理的连接
try:
conn = psycopg2.connect(
dbname="example_db",
user="user",
password="password",
host="localhost",
port="5432"
)
# 使用DictCursor获取命名列
with conn.cursor(cursor_factory=DictCursor) as cursor:
# 事务示例
try:
cursor.execute("BEGIN")
cursor.execute("""
INSERT INTO orders (customer_id, total)
VALUES (%s, %s) RETURNING id
""", (customer_id, total))
order_id = cursor.fetchone()['id']
cursor.execute("""
INSERT INTO order_items (order_id, product_id, quantity)
VALUES (%s, %s, %s)
""", (order_id, product_id, quantity))
conn.commit()
except:
conn.rollback()
raise
finally:
conn.close()
网络I/O
HTTP请求(使用requests)
import requests
# GET请求
response = requests.get('https://api.example.com/data')
data = response.json()
# POST请求与JSON
payload = {'key': 'value'}
headers = {'Content-Type': 'application/json'}
response = requests.post('https://api.example.com/create',
json=payload,
headers=headers)
# 使用流式下载文件
with requests.get('https://example.com/large_file', stream=True) as r:
r.raise_for_status()
with open('large_file.dat', 'wb') as f:
for chunk in r.iter_content(chunk_size=8192):
f.write(chunk)
套接字编程
import socket
# TCP服务器
def start_server():
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('localhost', 8000))
server_socket.listen(5)
while True:
client_socket, address = server_socket.accept()
data = client_socket.recv(1024)
client_socket.send(b"已收到:" + data)
client_socket.close()
# TCP客户端
def client_request():
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(('localhost', 8000))
client_socket.send(b"你好,服务器!")
response = client_socket.recv(1024)
client_socket.close()
return response
标准I/O
输入/输出流
import sys
# 标准输出
sys.stdout.write('你好\n')
print('你好', file=sys.stdout)
# 标准错误
sys.stderr.write('错误信息\n')
print('错误', file=sys.stderr)
# 标准输入
user_input = sys.stdin.readline()
# 重定向stdout
original_stdout = sys.stdout
with open('output.log', 'w') as f:
sys.stdout = f
print('这会写入文件')
sys.stdout = original_stdout
输入处理
# 基本输入
name = input('请输入你的名字:')
# 特定类型输入
age = int(input('请输入你的年龄:'))
height = float(input('请输入你的身高:'))
# 多个输入
x, y = map(int, input('请输入两个数字:').split())
内存I/O
StringIO和BytesIO
from io import StringIO, BytesIO
# 用于文本的StringIO
output = StringIO()
output.write('你好,')
output.write('世界!')
content = output.getvalue() # '你好,世界!'
output.close()
# 用于二进制数据的BytesIO
binary_output = BytesIO()
binary_output.write(b'Binary data')
binary_content = binary_output.getvalue()
binary_output.close()
异步I/O
使用asyncio
import asyncio
import aiofiles
import aiohttp
async def read_file_async():
async with aiofiles.open('large_file.txt') as file:
content = await file.read()
return content
async def fetch_url_async(url):
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
return await response.text()
async def main():
# 并行I/O操作
file_content, web_content = await asyncio.gather(
read_file_async(),
fetch_url_async('https://example.com')
)
return file_content, web_content
# 运行异步代码
if __name__ == '__main__':
asyncio.run(main())
最佳实践
错误处理
# 文件操作
try:
with open('file.txt', 'r') as file:
content = file.read()
except FileNotFoundError:
print('文件不存在')
except PermissionError:
print('权限被拒绝')
except IOError as e:
print(f'发生I/O错误:{e}')
# 数据库操作
try:
with conn.cursor() as cursor:
cursor.execute('SELECT * FROM users')
except mysql.connector.Error as err:
print(f"数据库错误:{err}")
conn.rollback()
finally:
conn.close()
资源管理
# 用于自动资源清理的上下文管理器
class DatabaseConnection:
def __init__(self, config):
self.config = config
self.conn = None
def __enter__(self):
self.conn = create_connection(self.config)
return self.conn
def __exit__(self, exc_type, exc_val, exc_tb):
if self.conn:
self.conn.close()
# 使用上下文管理器
with DatabaseConnection(config) as conn:
cursor = conn.cursor()
cursor.execute('SELECT * FROM users')
性能优化
# 高效的大文件读取
def read_large_file(file_path, chunk_size=8192):
with open(file_path, 'rb') as f:
while True:
chunk = f.read(chunk_size)
if not chunk:
break
yield chunk
# 批量数据库操作
def batch_insert(cursor, data, batch_size=1000):
for i in range(0, len(data), batch_size):
batch = data[i:i + batch_size]
cursor.executemany(
'INSERT INTO table (column) VALUES (?)',
batch
)
记录I/O操作
import logging
# 配置日志
logging.basicConfig(
filename='io_operations.log',
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
# 记录I/O操作
def safe_file_operation(file_path, operation):
try:
with open(file_path, 'r') as file:
result = operation(file)
logging.info(f'成功处理文件 {file_path}')
return result
except Exception as e:
logging.error(f'处理文件 {file_path} 时出错:{str(e)}')
raise
本指南涵盖了Python中I/O操作的基本方面,提供了处理各种类型输入和输出的实用示例和最佳实践。在处理大规模I/O操作时,请记住始终妥善处理资源、实施适当的错误处理,并考虑性能影响。