1. Python输入输出基础:程序与世界的桥梁
在编程世界中,输入输出(I/O)是程序与外界交互的核心通道。就像人类通过语言交流一样,程序也需要"说"和"听"的能力。Python作为一门强调可读性和实用性的语言,提供了极其简洁而强大的I/O工具集。
1.1 输出功能:print()的全面解析
print()函数是Python中最基础也最常用的输出工具,它的完整签名如下:
python复制print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)
让我们通过一个实际案例来理解每个参数的作用:
python复制# 打印三个变量,用"|"分隔,末尾添加"---"
name = "Alice"
age = 25
score = 89.5
print(name, age, score, sep=" | ", end="---\n")
# 输出到文件
with open('output.log', 'w') as f:
print("Error occurred!", file=f)
注意:flush参数控制是否立即刷新输出缓冲区。在实时日志记录等场景中,设置flush=True可以确保信息立即显示,而不是等待缓冲区满。
1.2 输入功能:input()的深入理解
input()函数虽然简单,但在实际应用中需要考虑多种情况:
python复制# 基础用法
user_input = input("请输入您的选择(1-3): ")
# 带默认值的输入
prompt = "请输入文件名 [默认:output.txt]: "
filename = input(prompt) or "output.txt"
# 超时处理(需要signal模块)
import signal
def timeout_handler(signum, frame):
raise TimeoutError("输入超时")
signal.signal(signal.SIGALRM, timeout_handler)
signal.alarm(5) # 5秒超时
try:
data = input("请在5秒内输入: ")
signal.alarm(0) # 取消计时器
except TimeoutError:
print("\n时间到,使用默认值")
data = "default"
2. 高级格式化技巧:让输出更专业
2.1 f-string的高级用法
Python 3.6引入的f-string是现代Python中最推荐的字符串格式化方式:
python复制# 基础变量插入
name = "Bob"
print(f"Hello, {name}!")
# 表达式计算
x, y = 3, 4
print(f"{x} * {y} = {x * y}")
# 格式规范
import datetime
now = datetime.datetime.now()
print(f"当前时间: {now:%Y-%m-%d %H:%M:%S}")
# 数字格式化
pi = 3.1415926
print(f"π值: {pi:.2f}") # 保留两位小数
print(f"十六进制: {255:#x}") # 0xff
# 对齐和填充
for i in range(1, 4):
print(f"Item {i:0>2}: {'*' * i}") # 01, 02, 03
2.2 多语言和特殊字符处理
在实际项目中,经常需要处理多语言和特殊字符:
python复制# Unicode字符
print("中文测试") # 直接支持Unicode
print("\N{grinning face}") # 使用Unicode名称
# 原始字符串
path = r"C:\new_folder\test" # 原始字符串,不转义
print(f"文件路径: {path}")
# 多行字符串
message = """
尊敬的{name}:
您的订单#{order_id}已发货。
预计到达时间: {delivery_time:%Y-%m-%d}
""".format(
name="王先生",
order_id=12345,
delivery_time=datetime.datetime.now() + datetime.timedelta(days=3)
)
print(message)
3. 实战应用:构建交互式命令行工具
3.1 命令行菜单系统
python复制def show_menu():
print("""
学生管理系统
============
1. 添加学生
2. 查询学生
3. 删除学生
4. 退出系统
""")
def get_choice():
while True:
try:
choice = int(input("请输入选项(1-4): "))
if 1 <= choice <= 4:
return choice
print("输入错误,请输入1-4的数字")
except ValueError:
print("请输入有效的数字!")
def main():
students = []
while True:
show_menu()
choice = get_choice()
if choice == 1:
name = input("学生姓名: ").strip()
age = int(input("学生年龄: "))
students.append({"name": name, "age": age})
print(f"成功添加学生: {name}")
elif choice == 2:
print("\n当前学生列表:")
for idx, student in enumerate(students, 1):
print(f"{idx}. {student['name']} - {student['age']}岁")
elif choice == 3:
if not students:
print("当前没有学生记录")
continue
student_id = int(input("输入要删除的学生编号: "))
if 1 <= student_id <= len(students):
removed = students.pop(student_id - 1)
print(f"已删除学生: {removed['name']}")
elif choice == 4:
print("感谢使用,再见!")
break
if __name__ == "__main__":
main()
3.2 数据验证与异常处理
健壮的命令行程序需要完善的输入验证:
python复制def get_positive_number(prompt):
"""获取正数输入"""
while True:
try:
value = float(input(prompt))
if value > 0:
return value
print("请输入大于0的数字")
except ValueError:
print("请输入有效的数字")
def get_yes_no(prompt):
"""获取是/否回答"""
while True:
answer = input(f"{prompt} (y/n): ").lower()
if answer in ('y', 'yes'):
return True
if answer in ('n', 'no'):
return False
print("请输入y(是)或n(否)")
def get_date(prompt):
"""获取日期输入"""
while True:
date_str = input(f"{prompt} (YYYY-MM-DD): ")
try:
return datetime.datetime.strptime(date_str, "%Y-%m-%d").date()
except ValueError:
print("日期格式错误,请使用YYYY-MM-DD格式")
4. 高级I/O技巧与性能优化
4.1 批量输出与性能
当需要输出大量数据时,直接使用print()可能效率低下:
python复制# 低效方式
for i in range(10000):
print(i) # 每次调用都有I/O开销
# 高效方式
output = []
for i in range(10000):
output.append(str(i))
print('\n'.join(output)) # 单次I/O操作
# 或者使用生成器表达式
print('\n'.join(str(i) for i in range(10000)))
4.2 日志记录与输出重定向
在实际项目中,合理使用日志系统比直接print更专业:
python复制import logging
# 基础配置
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('app.log'),
logging.StreamHandler()
]
)
logger = logging.getLogger(__name__)
def process_data(data):
try:
logger.info("开始处理数据")
# 处理逻辑...
logger.debug(f"处理中间结果: {data[:100]}...")
logger.info("数据处理完成")
except Exception as e:
logger.error(f"处理失败: {str(e)}", exc_info=True)
4.3 终端颜色与样式
在命令行工具中,使用颜色可以提升用户体验:
python复制class TerminalColors:
HEADER = '\033[95m'
OKBLUE = '\033[94m'
OKGREEN = '\033[92m'
WARNING = '\033[93m'
FAIL = '\033[91m'
ENDC = '\033[0m'
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
print(f"{TerminalColors.WARNING}警告: 磁盘空间不足!{TerminalColors.ENDC}")
print(f"{TerminalColors.OKGREEN}操作成功完成{TerminalColors.ENDC}")
5. 跨平台兼容性与最佳实践
5.1 处理不同操作系统的换行符
Windows和Unix-like系统使用不同的换行符:
python复制import os
# 跨平台换行符
print("第一行", end=os.linesep)
print("第二行")
# 写入文件时指定换行符
with open('output.txt', 'w', newline='\n') as f: # 强制使用Unix换行符
print("跨平台兼容内容", file=f)
5.2 字符编码处理
正确处理不同编码对于国际化应用至关重要:
python复制# 显式指定编码
with open('data.txt', 'w', encoding='utf-8') as f:
print("中文内容", file=f)
# 处理编码错误
try:
print("特殊字符: café".encode('ascii'))
except UnicodeEncodeError:
print("处理非ASCII字符时需要指定编码")
# 最佳实践:始终明确编码
import sys
if sys.stdout.encoding != 'UTF-8':
sys.stdout.reconfigure(encoding='utf-8')
5.3 输入密码的安全处理
对于敏感信息输入,使用getpass模块更安全:
python复制import getpass
def get_credentials():
username = input("用户名: ")
password = getpass.getpass("密码: ")
return username, password
try:
user, pwd = get_credentials()
print(f"用户 {user} 登录成功")
except getpass.GetPassWarning:
print("密码输入可能不安全")
6. 实际项目中的I/O设计模式
6.1 基于生成器的管道处理
处理大量数据时,使用生成器可以节省内存:
python复制def read_large_file(filename):
"""逐行读取大文件"""
with open(filename, 'r', encoding='utf-8') as f:
for line in f:
yield line.strip()
def process_data(lines):
"""处理数据管道"""
for line in lines:
if not line or line.startswith('#'):
continue
yield line.upper()
def write_output(lines, filename):
"""写入处理结果"""
with open(filename, 'w', encoding='utf-8') as f:
for line in lines:
print(line, file=f)
# 构建处理管道
lines = read_large_file('input.txt')
processed = process_data(lines)
write_output(processed, 'output.txt')
6.2 上下文管理器的高级应用
自定义上下文管理器可以更好地控制I/O资源:
python复制class IndentedOutput:
def __init__(self, indent=4):
self.indent = ' ' * indent
self.original_write = None
def __enter__(self):
"""进入上下文时重定向sys.stdout"""
import sys
self.original_write = sys.stdout.write
def new_write(text):
if text.strip():
text = text.replace('\n', f'\n{self.indent}')
text = f"{self.indent}{text}"
self.original_write(text)
sys.stdout.write = new_write
return self
def __exit__(self, exc_type, exc_val, exc_tb):
"""退出上下文时恢复sys.stdout"""
import sys
sys.stdout.write = self.original_write
# 使用示例
print("未缩进的输出")
with IndentedOutput():
print("这段输出会自动缩进")
print("多行文本也会\n正确缩进处理")
print("恢复普通输出")
6.3 基于类的I/O封装
对于复杂项目,将I/O操作封装到类中更易维护:
python复制class ConsoleIO:
"""封装控制台I/O操作"""
def __init__(self, input_stream=None, output_stream=None):
self.input = input_stream or input
self.output = output_stream or print
def prompt_choice(self, question, options):
"""提示用户从选项中选择"""
self.output(f"\n{question}")
for i, option in enumerate(options, 1):
self.output(f"{i}. {option}")
while True:
try:
choice = int(self.input("请选择: "))
if 1 <= choice <= len(options):
return choice - 1 # 返回索引
self.output(f"请输入1-{len(options)}之间的数字")
except ValueError:
self.output("请输入有效的数字")
def show_progress(self, current, total, bar_length=50):
"""显示进度条"""
percent = current / total
arrow = '=' * int(round(percent * bar_length) - 1) + '>'
spaces = ' ' * (bar_length - len(arrow))
self.output(f"\r进度: [{arrow + spaces}] {int(percent * 100)}%", end='')
if current == total:
self.output() # 完成时换行
# 使用示例
io = ConsoleIO()
choice = io.prompt_choice("请选择操作", ["新增", "查询", "删除", "退出"])
for i in range(101):
io.show_progress(i, 100)