Python 第十三节 Python中各种输入输出方案详解及注意事项
·
前言
Python 中各种输入输出使用方案,如:包括表达式语句、print()函数等,以及str()、repr()转换函数和字符串对齐填充方法,还讲解了str.format()格式化输出和旧式%操作符用法。还涉及键盘输入的input()函数,文件读写的open()函数及多种模式,文件对象的读写、指针操作等方法
1. 基本输入输出函数
1.1 标准输入输出
input() 函数
# 基本用法
name = input("请输入您的姓名: ")
print(f"你好, {name}!")
# 类型转换
age = int(input("请输入您的年龄: "))
height = float(input("请输入您的身高(米): "))
print(f"年龄: {age}, 身高: {height}")
print() 函数
# 基本输出
print("Hello, World!")
# 输出多个值
name = "Andy"
age = 18
print("姓名:", name, "年龄:", age)
# 格式化输出
print(f"姓名: {name}, 年龄: {age}")
print("姓名: {}, 年龄: {}".format(name, age))
print("姓名: %s, 年龄: %d" % (name, age))
# 控制分隔符和结束符
print("Python", "Java", "C++", sep=" | ", end="\n---\n")
1.2 格式化输出详解
f-string (Python 3.6+)
name = "Bob"
age = 30
salary = 5000.50
# 基本用法
print(f"{name} is {age} years old")
# 数字格式化
print(f"工资: {salary:.2f}") # 保留2位小数
print(f"年龄: {age:05d}") # 5位数字,前面补零
print(f"十六进制: {age:#x}") # 十六进制
print(f"百分比: {0.75:.1%}") # 百分比
# 表达式计算
a, b = 5, 3
print(f"{a} + {b} = {a + b}")
print(f"{a} × {b} = {a * b}")
str.format() 方法
# 位置参数
print("{0} 喜欢 {1} 和 {2}".format("小明", "Python", "Java"))
print("{1} 在 {0} 之前".format("B", "A"))
# 关键字参数
print("姓名: {name}, 年龄: {age}".format(name="Alice", age=25))
# 混合使用
print("{0} 的 {item} 价格是 {price:.2f}".format("商店", item="苹果", price=5.99))
# 对齐和填充
print("{:>10}".format("右对齐")) # 右对齐,宽度10
print("{:<10}".format("左对齐")) # 左对齐,宽度10
print("{:^10}".format("居中")) # 居中,宽度10
print("{:*^10}".format("居中")) # 居中,用*填充
2. 文件输入输出
2.1 文件基本操作
打开和关闭文件
# 基本文件写入
with open('example.txt', 'w', encoding='utf-8') as file:
file.write("Hello, World!\n")
file.write("这是第二行\n")
# 基本文件读取
with open('example.txt', 'r', encoding='utf-8') as file:
content = file.read()
print(content)
# 不使用 with 语句(不推荐)
file = open('example.txt', 'r')
try:
content = file.read()
finally:
file.close()
文件打开模式
常用如下:
‘r’ :只读(默认)
‘r+’:可读可写
‘w’ :写入,会覆盖已有文件
‘w+’:打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件
‘x’ :排他性创建,文件已存在则失败
‘a’ :追加,在文件末尾添加
‘b’ :二进制模式
‘t’ :文本模式(默认)
‘+’ :更新(可读可写)
2.2 文件读取方法
# 读取整个文件
with open('example.txt', 'r', encoding='utf-8') as file:
content = file.read()
print("整个文件内容:")
print(content)
# 逐行读取
with open('example.txt', 'r', encoding='utf-8') as file:
print("逐行读取:")
line = file.readline()
while line:
print(line.strip()) # strip() 去除换行符
line = file.readline()
# 读取所有行到列表
with open('example.txt', 'r', encoding='utf-8') as file:
lines = file.readlines()
print("所有行:")
# enumerate(sequence, [start=0]) 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中
# sequence 一个序列、迭代器或其他支持迭代对象
# start 下标起始位置的值
for i, line in enumerate(lines, 1):
print(f"第{i}行: {line.strip()}")
# 使用迭代器逐行读取(推荐用于大文件)
with open('example.txt', 'r', encoding='utf-8') as file:
print("使用迭代器:")
for line_num, line in enumerate(file, 1):
print(f"第{line_num}行: {line.strip()}")
2.3 文件写入方法
# 写入字符串
with open('output.txt', 'w', encoding='utf-8') as file:
file.write("这是第一行\n")
file.write("这是第二行\n")
# 写入多行
lines = ["第一行\n", "第二行\n", "第三行\n"]
with open('output.txt', 'w', encoding='utf-8') as file:
file.writelines(lines)
# 追加模式
with open('output.txt', 'a', encoding='utf-8') as file:
file.write("这是追加的内容\n")
# 批量写入数据
data = [
{"name": "Alice", "age": 25, "city": "Beijing"},
{"name": "Bob", "age": 30, "city": "Shanghai"},
{"name": "Charlie", "age": 35, "city": "Guangzhou"}
]
with open('data.csv', 'w', encoding='utf-8') as file:
file.write("姓名,年龄,城市\n")
for person in data:
file.write(f"{person['name']},{person['age']},{person['city']}\n")
3. 二进制文件操作
# 二进制写入
with open('binary_data.bin', 'wb') as file:
file.write(b'\x48\x65\x6c\x6c\x6f') # "Hello" 的二进制
# 二进制读取
with open('binary_data.bin', 'rb') as file:
data = file.read()
print("二进制数据:", data)
print("转换为字符串:", data.decode('utf-8'))
# 图片文件复制
def copy_image(source_path, target_path):
try:
with open(source_path, 'rb') as source:
with open(target_path, 'wb') as target:
# 分块读取大文件
while True:
chunk = source.read(4096) # 每次读取4KB
if not chunk:
break
target.write(chunk)
print("文件复制成功!")
except FileNotFoundError:
print("文件不存在!")
except Exception as e:
print(f"发生错误: {e}")
# 使用示例
copy_image('source.jpg', 'copy.jpg')
4. JSON 文件操作
import json
# 数据准备
data = {
"employees": [
{"name": "Alice", "age": 25, "department": "IT"},
{"name": "Bob", "age": 30, "department": "HR"},
{"name": "Charlie", "age": 35, "department": "Finance"}
],
"company": "Tech Corp"
}
# 写入 JSON 文件
with open('data.json', 'w', encoding='utf-8') as file:
json.dump(data, file, ensure_ascii=False, indent=2)
# 读取 JSON 文件
with open('data.json', 'r', encoding='utf-8') as file:
loaded_data = json.load(file)
print("JSON 数据:")
print(json.dumps(loaded_data, indent=2, ensure_ascii=False))
# JSON 字符串操作
json_str = json.dumps(data, ensure_ascii=False, indent=2)
print("JSON 字符串:")
print(json_str)
# 从字符串加载
parsed_data = json.loads(json_str)
print("解析后的数据:", parsed_data['company'])
5. CSV 文件操作
import csv
# 写入 CSV 文件
data = [
['姓名', '年龄', '城市', '工资'],
['Alice', '25', '北京', '5000'],
['Bob', '30', '上海', '6000'],
['Charlie', '35', '广州', '7000']
]
with open('employees.csv', 'w', encoding='utf-8', newline='') as file:
writer = csv.writer(file)
writer.writerows(data)
# 读取 CSV 文件
with open('employees.csv', 'r', encoding='utf-8') as file:
reader = csv.reader(file)
print("CSV 文件内容:")
for row in reader:
print(row)
# 使用字典方式读写 CSV
employees = [
{'name': 'Alice', 'age': 25, 'city': 'Beijing', 'salary': 5000},
{'name': 'Bob', 'age': 30, 'city': 'Shanghai', 'salary': 6000},
{'name': 'Charlie', 'age': 35, 'city': 'Guangzhou', 'salary': 7000}
]
# 字典写入
with open('employees_dict.csv', 'w', encoding='utf-8', newline='') as file:
fieldnames = ['name', 'age', 'city', 'salary']
writer = csv.DictWriter(file, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(employees)
# 字典读取
with open('employees_dict.csv', 'r', encoding='utf-8') as file:
reader = csv.DictReader(file)
print("字典方式读取:")
for row in reader:
print(f"{row['name']} - {row['city']} - ¥{row['salary']}")
6. 高级输入输出技巧
6.1 上下文管理器与自定义输出
class TeeOutput:
"""同时输出到控制台和文件"""
def __init__(self, filename):
self.file = open(filename, 'w', encoding='utf-8')
self.stdout = sys.stdout
def write(self, text):
self.file.write(text)
self.stdout.write(text)
def flush(self):
self.file.flush()
self.stdout.flush()
def close(self):
self.file.close()
# 使用示例
import sys
# 保存原来的标准输出
original_stdout = sys.stdout
try:
# 重定向输出
tee = TeeOutput('output.log')
sys.stdout = tee
print("这行会同时显示在控制台和文件中")
print("另一行输出")
finally:
# 恢复标准输出
sys.stdout = original_stdout
tee.close()
6.2 进度条显示
import time
import sys
def progress_bar(iteration, total, prefix='', suffix='', length=50, fill='█'):
"""
显示进度条
"""
percent = f"{100 * (iteration / float(total)):.1f}"
filled_length = int(length * iteration // total)
bar = fill * filled_length + '-' * (length - filled_length)
print(f'\r{prefix} |{bar}| {percent}% {suffix}', end='\r')
if iteration == total:
print()
# 使用示例
total_items = 100
for i in range(total_items + 1):
time.sleep(0.05) # 模拟工作
progress_bar(i, total_items, prefix='进度:', suffix='完成')
7. 注意事项和最佳实践
7.1 文件操作注意事项
# 1. 始终使用 with 语句
# ❌ 不推荐
file = open('test.txt', 'r')
content = file.read()
file.close() # 可能忘记关闭
# ✅ 推荐
with open('test.txt', 'r') as file:
content = file.read()
# 2. 处理文件不存在的情况
try:
with open('nonexistent.txt', 'r') as file:
content = file.read()
except FileNotFoundError:
print("文件不存在!")
except PermissionError:
print("没有文件访问权限!")
except Exception as e:
print(f"读取文件时发生错误: {e}")
# 3. 指定文件编码
# ❌ 可能在不同系统上出现编码问题
with open('file.txt', 'r') as file:
content = file.read()
# ✅ 明确指定编码
with open('file.txt', 'r', encoding='utf-8') as file:
content = file.read()
# 4. 大文件处理
def process_large_file(filename):
"""处理大文件的正确方式"""
with open(filename, 'r', encoding='utf-8') as file:
for line in file: # 逐行读取,内存友好
process_line(line.strip())
# 5. 路径处理
import os
from pathlib import Path
# 使用 pathlib(现代方式)
file_path = Path('data') / 'subfolder' / 'file.txt'
with open(file_path, 'w') as file:
file.write("内容")
# 检查文件是否存在
if file_path.exists():
print("文件存在")
7.2 输入验证和安全
def get_valid_input(prompt, input_type=str, validation_func=None):
"""
获取有效的用户输入
Args:
prompt: 提示信息
input_type: 输入类型
validation_func: 自定义验证函数
"""
while True:
try:
user_input = input(prompt)
if input_type != str:
user_input = input_type(user_input)
if validation_func and not validation_func(user_input):
raise ValueError("输入值不符合要求")
return user_input
except ValueError as e:
print(f"输入无效: {e},请重新输入")
# 使用示例
# 获取年龄(1-150之间)
age = get_valid_input(
"请输入年龄: ",
int,
lambda x: 1 <= x <= 150
)
# 获取非空字符串
name = get_valid_input(
"请输入姓名: ",
validation_func=lambda x: len(x.strip()) > 0
)
print(f"姓名: {name}, 年龄: {age}")
8. 实际应用案例
8.1 配置文件管理
import configparser
import json
class ConfigManager:
"""配置文件管理器"""
def __init__(self, config_file='config.ini'):
self.config_file = config_file
self.config = configparser.ConfigParser()
def load_config(self):
"""加载配置"""
try:
self.config.read(self.config_file, encoding='utf-8')
except Exception as e:
print(f"加载配置文件失败: {e}")
def save_config(self):
"""保存配置"""
try:
with open(self.config_file, 'w', encoding='utf-8') as file:
self.config.write(file)
except Exception as e:
print(f"保存配置文件失败: {e}")
def get_setting(self, section, key, default=None):
"""获取配置项"""
try:
return self.config.get(section, key)
except (configparser.NoSectionError, configparser.NoOptionError):
return default
# 使用示例
config = ConfigManager()
config.load_config()
database_host = config.get_setting('Database', 'host', 'localhost')
database_port = config.get_setting('Database', 'port', '3306')
print(f"数据库连接: {database_host}:{database_port}")
8.2 日志记录系统
import logging
from datetime import datetime
def setup_logging(log_file='app.log'):
"""设置日志系统"""
# 创建日志器
logger = logging.getLogger('MyApp')
logger.setLevel(logging.DEBUG)
# 避免重复添加处理器
if not logger.handlers:
# 文件处理器
file_handler = logging.FileHandler(log_file, encoding='utf-8')
file_handler.setLevel(logging.DEBUG)
# 控制台处理器
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)
# 格式化器
formatter = logging.Formatter(
'%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
file_handler.setFormatter(formatter)
console_handler.setFormatter(formatter)
# 添加处理器
logger.addHandler(file_handler)
logger.addHandler(console_handler)
return logger
# 使用示例
logger = setup_logging()
logger.info("应用程序启动")
logger.debug("调试信息")
logger.warning("警告信息")
logger.error("错误信息")
总结
关键要点:
输入处理:使用 input() 获取用户输入,注意类型转换和验证
输出格式化:优先使用 f-string,其次是 str.format()
文件操作:始终使用 with 语句,明确指定编码
异常处理:合理处理文件操作可能出现的异常
大文件处理:使用迭代方式逐行或分块处理
数据持久化:根据数据类型选择合适的格式(JSON、CSV、二进制等)
最佳实践:
- 使用
pathlib处理文件路径 - 为文本文件明确指定编码(
推荐 UTF-8) - 使用日志模块代替简单的
print()进行调试和记录 - 对用户输入进行充分的验证和清理
- 在处理敏感数据时注意安全性
这些输入输出方法是 Python 编程的基础,熟练掌握它们对于开发各种应用程序至关重要。
更多推荐
所有评论(0)