前言

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、二进制等)

最佳实践:

  1. 使用 pathlib 处理文件路径
  2. 为文本文件明确指定编码(推荐 UTF-8
  3. 使用日志模块代替简单的 print() 进行调试和记录
  4. 对用户输入进行充分的验证和清理
  5. 在处理敏感数据时注意安全性

这些输入输出方法是 Python 编程的基础,熟练掌握它们对于开发各种应用程序至关重要。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐