Python新手关于def main()的困惑:pandas处理CSV与模块复用问题
逐问题解答
1. 赋值新列时报df未定义的原因
核心问题是函数调用链路没有传递df的引用:
- 你定义计算函数时虽然将df设为入参,但在
main函数中调用multiply_by_3()、multiply_by_5()时没有传入任何参数,整个执行流程中没有df对象的作用域,自然触发未定义报错。 - 修正逻辑:所有计算环节透传df引用,计算完成后通过
df['列名'] = 计算结果直接将新列追加到原DataFrame上。DataFrame是可变对象,这类赋值会直接修改原df的结构。
注意两处可优化的问题: - 函数命名与实际功能不匹配:
multiply_by_3实际实现的是A列乘2的逻辑,需调整为与功能一致的命名,符合代码可维护性最佳实践。 - 列计算可直接使用pandas向量化运算,不需要写列表推导式遍历每一行元素,直接执行
df['A'] * 2即可生成对应列,运行效率比循环遍历高一个数量级。
2. 支持批量处理的独立模块main函数设计方案
要做成可复用的独立模块,需将不同层级的逻辑拆分独立,避免全堆在main函数中:
- 第一级:抽离单文件处理核心逻辑,作为独立可调用函数,入参为输入csv路径、输出csv路径,内部完成读文件、列计算、存文件的全流程。
- 第二级:抽离批量遍历文件夹逻辑,入参为源目录路径、输出目录路径,内部遍历源目录下所有后缀为.csv的文件,逐个调用单文件处理函数。
- 第三级:main函数仅负责配置「直接运行脚本时」的默认参数(比如将提到的默认路径
D:/Files/、单独的处理结果输出路径D:/Files/processed/作为默认值传入批量处理函数)。 - 必须添加
if __name__ == "__main__":判断块包裹main函数的调用,这是Python模块的核心设计规则:仅当脚本被直接运行时才会执行main内的逻辑,被其他脚本导入时不会自动触发批量处理流程。
3. 模块导入时的整套逻辑调用规则
- 当你将这个脚本保存为
csv_batch_processor.py,在其他业务脚本中导入时,因为有if __name__ == "__main__"的拦截,main函数里的默认逻辑不会自动执行,完全不影响你导入单个计算函数做单独使用。 - 导入后运行整套批量处理逻辑有两种正规用法:
- 推荐做法:直接导入提前抽好的批量处理函数,自定义传入需要的源路径、输出路径,灵活度更高,示例代码:
from csv_batch_processor import batch_process_folder # 自定义传入需要处理的文件夹路径 batch_process_folder(input_dir="E:/my_csv/", output_dir="E:/my_output/") - 非推荐做法:如果一定要直接运行整套main逻辑,导入后手动调用main函数即可,示例代码:
import csv_batch_processor csv_batch_processor.main()
- 推荐做法:直接导入提前抽好的批量处理函数,自定义传入需要的源路径、输出路径,灵活度更高,示例代码:
修正后的可直接运行的完整代码
import pandas as pd from pathlib import Path # 单文件核心列计算逻辑 def calc_new_columns(df: pd.DataFrame) -> pd.DataFrame: df['A*2'] = df['A'] * 2 df['B*5'] = df['B'] * 5 df['A*2 + B*5'] = df['A*2'] + df['B*5'] return df # 单文件全流程处理 def process_single_csv(input_path: Path, output_path: Path): df = pd.read_csv(input_path) processed_df = calc_new_columns(df) processed_df.to_csv(output_path, index=False) # 批量文件夹处理 def batch_process_folder(input_dir: str, output_dir: str): input_path = Path(input_dir) output_path = Path(output_dir) # 自动创建输出文件夹,避免路径不存在报错 output_path.mkdir(parents=True, exist_ok=True) # 遍历源目录下所有CSV文件 for csv_file in input_path.glob("*.csv"): # 生成带前缀的输出文件名,避免覆盖原文件 out_file = output_path / f"processed_{csv_file.name}" process_single_csv(csv_file, out_file) # 脚本直接运行时的入口配置 def main(): DEFAULT_INPUT_DIR = "D:/Files/" DEFAULT_OUTPUT_DIR = "D:/Files/processed/" batch_process_folder(DEFAULT_INPUT_DIR, DEFAULT_OUTPUT_DIR) # 核心判断:直接运行脚本时才执行main,导入为模块时不触发 if __name__ == "__main__": main()
内容的提问来源于stack exchange,提问作者user3424575
相关产品推荐
相关产品推荐

