AI编程新体验:InternLM2-Chat-1.8B结对编程实战演示
AI编程新体验:InternLM2-Chat-1.8B结对编程实战演示
1. 引言
你有没有过这样的经历?深夜对着屏幕,想写一个功能,思路卡壳,身边又没人可以讨论。或者,写了一段代码,总觉得哪里不对劲,但又说不出来。这时候,如果有一个随时在线、思路清晰的编程伙伴,那该多好。
今天,我们就来体验一下这种全新的编程方式。我找来了InternLM2-Chat-1.8B模型,让它扮演我的“结对编程”搭档。我们一起来完成一个具体的编程任务:用Python写一个递归遍历目录并统计文件类型的脚本。
这不是一次简单的代码生成演示,而是一场真实的、交互式的编程对话。我会像和真人搭档一样,向它提出需求,讨论实现思路,让它写代码,然后对代码提出疑问,再让它修改优化。整个过程,你会看到AI如何理解问题、如何思考、如何回应反馈,以及最终如何交付一个可用的解决方案。
准备好了吗?让我们开始这场特别的编程协作。
2. 任务设定与开场
我决定从一个非常具体且常见的需求入手:统计一个文件夹及其所有子文件夹中,各种类型文件的数量。比如,一个项目目录里有多少个.py文件、多少个.txt文件、多少个图片文件等等。这个需求看似简单,但涉及文件系统操作、递归逻辑和数据结构统计,很适合检验AI的编程协作能力。
我打开了与InternLM2-Chat-1.8B的对话窗口,输入了我们的第一个“用户故事”:
我(开发者):你好,我需要写一个Python脚本。它的功能是:递归遍历一个指定的目录,统计该目录下(包括所有子目录)各种文件类型的数量,并输出一个清晰的统计报告。你能帮我一步步实现吗?
AI(结对伙伴):当然可以。这是一个很实用的功能。我们可以分步来实现它。首先,我们需要明确几个关键点:
- 输入:脚本需要接收一个目录路径作为参数。
- 核心逻辑:递归遍历目录树,收集所有文件的扩展名。
- 统计:对扩展名进行计数。
- 输出:将统计结果以易读的方式打印出来。
我们先从最核心的递归遍历和文件收集开始写,你觉得怎么样?
看,它没有直接扔给我一大段代码,而是先梳理了需求,并提出了一个实现框架。这种“先讨论,再动手”的方式,正是结对编程的精髓。我同意了它的建议。
3. 第一轮迭代:核心遍历与统计
基于我们达成的共识,AI输出了第一版代码。
import os
from collections import defaultdict
def count_file_types(directory_path):
"""
递归统计目录中各类文件的数量。
Args:
directory_path (str): 要统计的根目录路径。
Returns:
dict: 一个字典,键为文件扩展名(如 '.txt'),值为该类型文件的数量。
"""
type_count = defaultdict(int)
for root, dirs, files in os.walk(directory_path):
for file in files:
# 获取文件扩展名,并将其转换为小写以确保统计一致性(如.TXT和.txt视为同一种)
_, ext = os.path.splitext(file)
ext = ext.lower()
# 对于没有扩展名的文件,将其归类为‘无扩展名’
if not ext:
ext = ‘no_extension’
type_count[ext] += 1
return type_count
if __name__ == "__main__":
target_dir = input("请输入要统计的目录路径: ").strip()
if os.path.isdir(target_dir):
result = count_file_types(target_dir)
print("\n文件类型统计结果:")
for ext, count in sorted(result.items()):
print(f" {ext}: {count} 个")
else:
print("错误:输入的路径不是一个有效的目录。")
代码看起来干净利落。它使用了os.walk来优雅地处理递归遍历,用defaultdict(int)来简化计数逻辑,还考虑到了文件扩展名大小写统一和无扩展名文件的情况。注释也写得清晰明了。
我运行了一下,针对我的一个测试目录,它输出了类似这样的结果:
文件类型统计结果:
.py: 15 个
.txt: 8 个
.md: 3 个
.jpg: 5 个
no_extension: 2 个
功能基本实现了。但作为一个挑剔的“搭档”,我觉得还有优化空间。于是,我提出了第一轮反馈。
4. 交互与优化:让输出更友好
我(开发者):代码运行得很好,核心功能没问题。不过,输出结果可以更友好一些吗?比如,把‘.py’显示为‘Python文件’,把‘no_extension’显示为‘无扩展名文件’。另外,能不能按文件数量从多到少排序?这样我一眼就能看出哪种文件最多。
AI(结对伙伴):很好的建议!让输出更人性化确实能提升使用体验。我们可以创建一个扩展名到类型描述的映射字典。对于未知的扩展名,可以保留原样。排序也很简单。我来修改一下输出部分的代码。
很快,它给出了修改后的版本,主要更新了if __name__ == “__main__”:部分:
# ... (count_file_types函数保持不变) ...
if __name__ == "__main__":
# 定义一个扩展名到友好名称的映射(可根据需要扩充)
friendly_names = {
‘.py’: ‘Python文件’,
‘.txt’: ‘文本文件’,
‘.md’: ‘Markdown文件’,
‘.jpg’: ‘JPEG图像’,
‘.png’: ‘PNG图像’,
‘.pdf’: ‘PDF文档’,
‘.zip’: ‘ZIP压缩包’,
‘no_extension’: ‘无扩展名文件’
}
target_dir = input("请输入要统计的目录路径: ").strip()
if os.path.isdir(target_dir):
result = count_file_types(target_dir)
# 按文件数量降序排序
sorted_items = sorted(result.items(), key=lambda x: x[1], reverse=True)
print(f"\n目录 ‘{target_dir}‘ 下的文件类型统计(按数量降序):")
print("-" * 50)
total_files = sum(result.values())
for ext, count in sorted_items:
# 获取友好名称,如果没有映射则使用扩展名本身
name = friendly_names.get(ext, ext)
print(f" {name:20} {count:4d} 个")
print("-" * 50)
print(f" 文件总数:{total_files} 个")
else:
print("错误:输入的路径不是一个有效的目录。")
再次运行,输出变成了:
目录 ‘./my_project‘ 下的文件类型统计(按数量降序):
--------------------------------------------------
Python文件 15 个
文本文件 8 个
JPEG图像 5 个
Markdown文件 3 个
.log 2 个
无扩展名文件 2 个
--------------------------------------------------
文件总数:35 个
这下看起来专业多了!不仅排序了,还有了友好的类型名称、分隔线和总计。对于映射表中没有的扩展名(如.log),它也做了回退处理,直接显示扩展名。
5. 深度探讨:处理隐藏文件与性能考量
代码已经很好用了,但我想把这次结对编程推向更深层次的讨论,看看AI能否处理一些边界情况和工程问题。
我(开发者):很棒!现在输出清晰多了。我还有两个问题想探讨:
- 有些系统文件或隐藏文件(比如以点开头的
.gitignore)可能我不需要统计。能否增加一个过滤选项?- 如果遍历一个非常大的目录(比如整个硬盘),这个脚本可能会占用较多内存,因为
os.walk是一次性遍历的。有没有更节省内存的迭代方式?
AI(结对伙伴):这两个都是非常实际的工程问题。
- 过滤隐藏文件:我们可以修改遍历逻辑,在统计前检查文件名。在Unix/Linux系统中,隐藏文件通常以点开头。我们可以添加一个参数来控制是否跳过它们。
- 内存优化:
os.walk默认是自顶向下的生成器,它本身不会一次性将所有结果加载到内存。但在极端深的目录树下,dirs和files列表可能会比较大。更节省内存的方式是使用os.scandir()自己写递归,它可以提供更高效的文件属性访问,并且我们可以更精细地控制遍历过程。为了平衡代码复杂性和实用性,我们先实现隐藏文件过滤功能。如果需要处理超大规模目录,我们可以再重构为基于
os.scandir的递归。你觉得这样可以吗?
我同意了它的分析。先解决过滤问题。它随后给出了增强版的count_file_types函数:
def count_file_types(directory_path, ignore_hidden=True):
"""
递归统计目录中各类文件的数量。
Args:
directory_path (str): 要统计的根目录路径。
ignore_hidden (bool): 是否忽略以点‘.’开头的隐藏文件。默认为True。
Returns:
dict: 一个字典,键为文件扩展名(如 ‘.txt‘),值为该类型文件的数量。
"""
type_count = defaultdict(int)
for root, dirs, files in os.walk(directory_path):
for file in files:
# 如果启用忽略隐藏文件,且文件名以点开头,则跳过
if ignore_hidden and file.startswith(‘.’):
continue
_, ext = os.path.splitext(file)
ext = ext.lower()
if not ext:
ext = ‘no_extension’
type_count[ext] += 1
return type_count
它增加了一个ignore_hidden参数,并在循环中增加了相应的判断逻辑。主程序调用时,可以传入这个参数。这个改动简单而有效。
关于第二个性能问题,AI虽然没有直接重写代码,但它清晰地解释了os.walk与os.scandir的差异,并给出了一个简化的伪代码思路,说明如何用后者实现更手动的、可能更省内存的递归。这表明它不仅能写代码,还能理解不同方案背后的权衡。
6. 最终成果与体验总结
经过几轮交互,我们得到了一个功能完善、输出友好、且考虑了一定边界情况的脚本。这场结对编程会话也接近尾声。
我(开发者):非常感谢!经过这几轮修改,这个脚本已经完全满足我的需求了,甚至比我想的还要周到。这次合作很愉快。
AI(结对伙伴):不客气!能帮到你很高兴。这个脚本现在具备了核心统计、友好输出、隐藏文件过滤等功能。如果你将来需要处理超大规模目录,或者想增加按文件大小统计、过滤特定目录等功能,我们可以继续在此基础上修改。随时可以再找我“结对”。
回顾整个会话,InternLM2-Chat-1.8B展现出了令人印象深刻的“结对编程”素养:
- 理解与拆解:它能准确理解“递归遍历统计文件类型”这个自然语言描述的需求,并将其拆解为输入、处理、输出等可执行的步骤。
- 代码实现能力:生成的Python代码结构清晰,使用了合适的标准库(
os,collections),并包含了基本的错误处理和边界情况考虑(如无扩展名文件)。 - 交互与迭代:它不仅能接受模糊的需求,更能根据具体的反馈进行精准修改。从“优化输出”到“增加过滤功能”,它都能快速理解意图并落实在代码上。
- 技术讨论深度:当被问及性能和高级方案时,它能指出
os.walk与os.scandir的区别,并进行权衡分析,这超出了简单的代码补全,进入了方案设计的层面。
当然,它并非完美。在整个过程中,我需要提出明确的、结构化的反馈。它更像一个反应迅速、知识渊博但需要明确引导的初级搭档。然而,这对于解决日常编程中那些“知道要做什么,但懒得敲细节”或者“想找个思路参考”的场景,已经绰绰有余。
7. 结语
这次与InternLM2-Chat-1.8B的结对编程实战,不仅仅是一次代码生成演示。它更像是一次对未来编程工作流的预演。AI不再是那个藏在自动补全后面的神秘工具,而是走到了台前,成为一个可以对话、可以讨论、可以共同迭代的编程伙伴。
它可能不会完全替代人类开发者天马行空的架构设计能力,但对于实现具体功能、编写样板代码、快速原型验证、甚至学习新的API用法来说,这样一个随时在线的“搭档”无疑能极大提升效率,减少孤独感,甚至能在思路上给你带来意想不到的启发。
下次当你面对一个编程任务时,不妨也试着向AI描述你的问题,和它聊一聊,一起写写看。你可能会发现,编程这件事,从此多了一份不一样的乐趣和可能。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。
更多推荐

所有评论(0)