Python I/O (输入/输出)操作:综合指南

输入/输出(I/O)操作是任何编程语言的基础,使程序能够与文件、数据库、网络和其他外部资源进行交互。本指南探讨Python强大的I/O功能,从基本文件操作到高级数据库交互。

目录

  1. 文件I/O
  2. 数据库I/O
  3. 网络I/O
  4. 标准I/O
  5. 内存I/O
  6. 异步I/O
  7. 最佳实践

文件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操作时,请记住始终妥善处理资源、实施适当的错误处理,并考虑性能影响。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Morpheon

打赏买咖啡~谢了

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值