Qwen3-4B模型代码生成能力展示:从需求描述到可运行Python脚本

最近在尝试各种AI代码生成工具,发现Qwen3-4B模型在理解自然语言需求并生成Python代码方面,表现确实让人眼前一亮。它不像有些工具那样,只能生成一些简单的代码片段,而是能根据你的描述,一步步构建出结构完整、考虑周全的脚本。

今天这篇文章,我就想带大家看看,当你用大白话描述一个编程需求时,Qwen3-4B是怎么把它变成一份可以直接运行的Python代码的。我会通过几个具体的例子,从简单的数据处理到稍复杂的网络请求,看看它生成的代码到底能不能用,好不好用。

1. 从一句话需求到完整脚本

很多人对AI写代码的印象还停留在“补全几行”的阶段。但Qwen3-4B给我的感觉是,它更像一个能听懂你需求的初级程序员搭档。你不需要懂什么设计模式或者复杂的库函数,只要把你想做的事情说清楚,它就能给你搭出一个像模像样的架子。

1.1 案例一:数据清洗与整理

我们从一个最常见的需求开始:数据清洗。假设你手头有一份CSV格式的销售数据,里面有些行数据不全,有些数字格式混乱,你想让AI帮你写个脚本来处理一下。

我给模型的提示词是这样的:“帮我写一个Python脚本,读取一个叫‘sales_data.csv’的文件,删除所有包含空值的行,然后把‘销售额’这一列的数字字符串(比如‘1,200.50’)转换成浮点数,最后把处理好的数据保存到‘cleaned_sales.csv’里。”

模型生成的代码是这样的:

import pandas as pd

def clean_sales_data(input_file, output_file):
    """
    清洗销售数据。
    
    参数:
        input_file (str): 输入CSV文件路径。
        output_file (str): 输出CSV文件路径。
    """
    try:
        # 1. 读取数据
        df = pd.read_csv(input_file)
        print(f"原始数据形状: {df.shape}")
        
        # 2. 删除包含任何空值的行
        df_cleaned = df.dropna()
        print(f"删除空值后形状: {df_cleaned.shape}")
        
        # 3. 清洗‘销售额’列(假设列名为‘销售额’)
        if '销售额' in df_cleaned.columns:
            # 移除逗号和货币符号,并转换为浮点数
            df_cleaned['销售额'] = df_cleaned['销售额'].astype(str).str.replace(',', '').str.replace('¥', '').str.replace('$', '').astype(float)
            print("‘销售额’列已转换为浮点数。")
        else:
            print("警告:未找到‘销售额’列。")
        
        # 4. 保存清洗后的数据
        df_cleaned.to_csv(output_file, index=False)
        print(f"清洗后的数据已保存至: {output_file}")
        
        return df_cleaned
        
    except FileNotFoundError:
        print(f"错误:找不到文件 {input_file}")
    except pd.errors.EmptyDataError:
        print("错误:文件为空。")
    except Exception as e:
        print(f"处理过程中发生未知错误: {e}")

# 使用示例
if __name__ == "__main__":
    input_csv = "sales_data.csv"
    output_csv = "cleaned_sales.csv"
    cleaned_df = clean_sales_data(input_csv, output_csv)
    if cleaned_df is not None:
        print(cleaned_df.head())

这段代码看完,第一感觉是“考虑得挺周全”。它没有简单地调用pd.read_csv就完事,而是做了好几件事:

  1. 结构清晰:把主要逻辑封装成了一个函数,还写了文档字符串,告诉你这个函数是干嘛的,参数是什么。
  2. 健壮性:加了try...except块来捕获可能出现的错误,比如文件找不到、文件是空的,或者其他意外情况,并且会打印出友好的错误提示,而不是让程序直接崩溃。
  3. 步骤明确:代码逻辑完全对应了我的需求:读取、删空值、转换格式、保存。在转换“销售额”时,它还考虑到了数字里可能包含的逗号和货币符号,用了一连串的.str.replace()来处理,这个细节很实用。
  4. 有交互反馈:在关键步骤后加了print语句,运行的时候你能看到它进行到哪一步了,处理了多少数据,这对调试和确认结果很有帮助。

我把这段代码复制下来,准备一个简单的sales_data.csv文件,里面故意放了一些空行和带逗号的数字,运行了一下,一次就成功了。生成的新文件里数据整整齐齐,数字也都能直接用来计算了。

1.2 案例二:自动发送邮件通知

第二个例子,我们玩点更“自动化”的。假设你写了个脚本每天跑,跑完了希望能自动发封邮件告诉你结果。

我给模型的提示是:“写一个Python函数,用SMTP发送邮件。需要能指定发件人、收件人列表、邮件主题、正文内容,并且支持添加附件。发件邮箱的SMTP服务器和密码通过参数传入。”

模型这次给出的代码更注重实用性和安全性:

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
from email.utils import formatdate
import os

def send_email_via_smtp(smtp_server, smtp_port, sender_email, sender_password,
                         receiver_emails, subject, body, attachment_paths=None):
    """
    使用SMTP协议发送邮件,支持附件。
    
    参数:
        smtp_server (str): SMTP服务器地址,如 'smtp.gmail.com'。
        smtp_port (int): SMTP服务器端口,如 587。
        sender_email (str): 发件人邮箱地址。
        sender_password (str): 发件人邮箱密码或授权码(建议使用授权码)。
        receiver_emails (list): 收件人邮箱地址列表。
        subject (str): 邮件主题。
        body (str): 邮件正文(纯文本)。
        attachment_paths (list, optional): 附件文件路径列表。默认为None。
    
    返回:
        bool: 发送成功返回True,失败返回False。
    """
    # 创建邮件对象
    msg = MIMEMultipart()
    msg['From'] = sender_email
    msg['To'] = ', '.join(receiver_emails)  # 多个收件人用逗号分隔
    msg['Date'] = formatdate(localtime=True)
    msg['Subject'] = subject
    
    # 添加邮件正文
    msg.attach(MIMEText(body, 'plain'))
    
    # 添加附件
    if attachment_paths:
        for file_path in attachment_paths:
            if os.path.isfile(file_path):
                with open(file_path, 'rb') as f:
                    file_data = f.read()
                file_name = os.path.basename(file_path)
                attachment = MIMEApplication(file_data, Name=file_name)
                attachment['Content-Disposition'] = f'attachment; filename="{file_name}"'
                msg.attach(attachment)
                print(f"附件 '{file_name}' 已添加。")
            else:
                print(f"警告:附件路径 '{file_path}' 不存在,已跳过。")
    
    # 发送邮件
    try:
        # 建立安全连接(TLS)
        server = smtplib.SMTP(smtp_server, smtp_port)
        server.starttls()  # 升级为TLS加密连接
        server.login(sender_email, sender_password)
        server.sendmail(sender_email, receiver_emails, msg.as_string())
        server.quit()
        print("邮件发送成功!")
        return True
    except smtplib.SMTPAuthenticationError:
        print("错误:邮箱认证失败,请检查邮箱和密码(授权码)。")
    except smtplib.SMTPException as e:
        print(f"SMTP错误:{e}")
    except Exception as e:
        print(f"发送邮件时发生未知错误:{e}")
    return False

# 使用示例
if __name__ == "__main__":
    # 替换为你的实际信息(特别注意:密码建议使用邮箱提供的授权码,而非登录密码)
    SMTP_SERVER = "smtp.example.com"
    SMTP_PORT = 587
    SENDER_EMAIL = "your_email@example.com"
    # 警告:不建议在代码中硬编码密码,建议从环境变量或配置文件中读取
    SENDER_PASSWORD = "your_authorization_code" 
    
    RECEIVERS = ["receiver1@example.com", "receiver2@example.com"]
    EMAIL_SUBJECT = "每日数据报告 - 完成"
    EMAIL_BODY = """
    你好,
    
    今日的数据处理脚本已成功运行。
    所有任务已完成,详细报告请查看附件。
    
    此邮件由自动化脚本发送。
    """
    ATTACHMENTS = ["./daily_report.pdf", "./error_log.txt"]  # 假设的附件路径
    
    success = send_email_via_smtp(
        smtp_server=SMTP_SERVER,
        smtp_port=SMTP_PORT,
        sender_email=SENDER_EMAIL,
        sender_password=SENDER_PASSWORD,
        receiver_emails=RECEIVERS,
        subject=EMAIL_SUBJECT,
        body=EMAIL_BODY,
        attachment_paths=ATTACHMENTS
    )
    
    if success:
        print("通知流程完毕。")
    else:
        print("邮件发送失败,请检查配置和网络。")

这段代码让我觉得惊喜的地方在于它的“安全意识”和“实用性”。它没有让我直接把密码写在代码里跑,而是在注释里明确警告“不建议硬编码密码”,并建议从环境变量读取。这在真正的项目协作中是个好习惯。

功能上,它完全满足需求:支持多个收件人、添加多个附件、发送纯文本正文。错误处理也覆盖了常见的认证失败和网络问题。示例部分写得很完整,我只需要填上自己的邮箱信息,就能立刻测试。我用自己的测试邮箱跑了一遍,成功收到了带附件的邮件,正文格式也正确。

2. 处理更复杂的逻辑:网页爬虫

看了两个偏重数据和处理流程的例子,我们再来试试更考验逻辑和外部库使用的场景——写一个网页爬虫。这个需求对代码的结构和异常处理要求更高。

我的需求描述是:“写一个Python脚本,爬取某个新闻网站首页的新闻标题和链接。要求使用requests和BeautifulSoup库,需要设置请求头模拟浏览器访问,处理网络请求异常和解析异常,并将结果以JSON格式保存到文件。”

模型生成的脚本如下:

import requests
from bs4 import BeautifulSoup
import json
import time
from urllib.parse import urljoin

def fetch_news_titles(url, headers=None):
    """
    从指定URL抓取新闻标题和链接。
    
    参数:
        url (str): 目标新闻网站的URL。
        headers (dict, optional): 请求头字典。默认为None,使用常见浏览器头。
    
    返回:
        list: 包含字典的列表,每个字典有'title'和'link'键。
              如果失败,返回空列表。
    """
    # 默认请求头,模拟浏览器访问
    if headers is None:
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
        }
    
    news_list = []
    
    try:
        print(f"正在请求: {url}")
        response = requests.get(url, headers=headers, timeout=10)
        response.raise_for_status()  # 如果状态码不是200,抛出HTTPError异常
        response.encoding = response.apparent_encoding  # 自动识别编码
        
    except requests.exceptions.Timeout:
        print("错误:请求超时。")
        return news_list
    except requests.exceptions.HTTPError as e:
        print(f"HTTP错误:{e}")
        return news_list
    except requests.exceptions.RequestException as e:
        print(f"请求异常:{e}")
        return news_list
    
    # 解析HTML
    try:
        soup = BeautifulSoup(response.text, 'html.parser')
        
        # 这里需要根据实际网站结构修改选择器
        # 示例:假设新闻标题在 <h2 class='news-title'> 标签内,链接在其中的 <a> 标签里
        news_items = soup.find_all('h2', class_='news-title')
        
        if not news_items:
            # 如果没找到,尝试其他常见选择器
            news_items = soup.find_all('a', class_='news-link')
            print("使用备用选择器查找。")
        
        for item in news_items:
            link_tag = item.find('a') if item.name == 'h2' else item
            if link_tag and link_tag.get('href'):
                title = link_tag.get_text(strip=True)
                # 处理相对链接
                link = urljoin(url, link_tag['href'])
                if title:  # 确保标题不为空
                    news_list.append({
                        'title': title,
                        'link': link
                    })
        
        print(f"成功提取 {len(news_list)} 条新闻。")
        
    except Exception as e:
        print(f"解析HTML时发生错误:{e}")
    
    return news_list

def save_to_json(data, filename):
    """将数据保存为JSON文件。"""
    try:
        with open(filename, 'w', encoding='utf-8') as f:
            json.dump(data, f, ensure_ascii=False, indent=4)
        print(f"数据已保存到: {filename}")
        return True
    except IOError as e:
        print(f"保存文件时出错: {e}")
        return False

def main():
    """主函数"""
    target_url = "https://example-news-site.com"  # 替换为实际的新闻网站URL
    output_file = "news_titles.json"
    
    print("开始爬取新闻...")
    news_data = fetch_news_titles(target_url)
    
    if news_data:
        if save_to_json(news_data, output_file):
            print("爬取任务成功完成!")
            # 打印前几条结果预览
            for i, news in enumerate(news_data[:3]):
                print(f"{i+1}. {news['title']}")
                print(f"   链接: {news['link']}\n")
        else:
            print("数据保存失败。")
    else:
        print("未爬取到任何新闻数据。")
    
    # 礼貌性延迟,避免对服务器造成压力
    time.sleep(2)

if __name__ == "__main__":
    main()

这个脚本就有点“专业选手”的味道了。它不仅仅是把功能实现,还体现了很多工程化的思考:

  1. 模块化设计:把核心的抓取功能fetch_news_titles和保存功能save_to_json分开,这样代码更清晰,也方便单独测试或重用。
  2. 健壮性优先:网络请求部分包裹了多层异常捕获,分别处理超时、HTTP错误和其他请求异常。解析部分也用了try...except,防止因为网页结构变化导致整个程序崩溃。
  3. 可配置与可扩展:请求头headers作为参数,方便用户自定义。注释里明确说明了news_items的选择器需要根据实际网站修改,并提供了一个备用查找逻辑,这比直接写死一个选择器要实用得多。
  4. 考虑实际环境:使用了urljoin来处理可能出现的相对链接,确保链接是完整的。在最后加了time.sleep(2),这是一个简单的反爬虫礼仪,体现了对目标网站的尊重。
  5. 输出友好:控制台打印了清晰的进度信息,成功后会预览前几条结果,让用户立刻知道抓取到了什么。

我找了一个结构简单的静态新闻页面,替换了target_url和选择器(将'h2', class_='news-title'改为对应的标签),脚本成功运行并输出了JSON文件。虽然面对复杂的、动态加载的现代网站它可能力有不逮,但对于基础的爬虫需求和学习目的来说,这个起点已经非常高了。

3. 生成代码的质量与可用性分析

通过上面几个案例,我们能对Qwen3-4B的代码生成能力有一个比较具体的感受。它不是单纯地堆砌代码,而是在尝试理解需求背后的意图,并生成可用、可读、可维护的代码。

首先,在功能完整性上,它生成的代码基本都能直接运行。像数据清洗脚本,你准备好CSV文件就能用;邮件发送脚本,填好邮箱配置就能发;爬虫脚本,修改一下目标URL和选择器就能跑。它默认生成的代码就包含了必要的导入、函数定义、主程序入口和示例用法,形成了一个完整的“脚本模板”,省去了用户自己搭建框架的时间。

其次,在代码可读性上,它做得不错。函数和变量命名基本符合英文语义(如clean_sales_data, fetch_news_titles),关键步骤有注释,复杂的逻辑处理(比如字符串替换链)也通过换行和注释让人能看懂。生成的函数通常还带有文档字符串,说明了参数和返回值,这对后续的代码阅读和维护很有帮助。

再者,在工程实践上,它展现出了超出预期的意识。比如异常处理几乎成了“标配”,这能防止脚本因意外错误而彻底失败。它会考虑安全性(如邮件密码的警告)、资源管理(如文件读取使用with语句)和网络礼仪(如爬虫的延迟)。虽然这些不一定每次都能做到完美,但这种倾向让生成的代码离“生产环境可用”更近了一步。

当然,它也不是万能的。对于极度复杂或需要特定领域知识的任务,它可能生成有缺陷或效率不高的代码。比如爬虫例子中,它无法知道目标网站真实的结构,选择器需要人工调整。但它的价值在于,提供了一个高质量、可运行的起点。开发者可以在这个基础上进行调试、优化和扩展,这比从零开始写要高效得多。

4. 总结

整体体验下来,Qwen3-4B在代码生成方面的能力是扎实且实用的。它特别适合那些有明确目标但不想纠缠于语法细节的场景,比如快速原型验证、编写重复性的工具脚本、学习某个库的基本用法,或者为某个复杂任务搭建初步框架。

它生成的代码,就像是一个细心且有一定经验的同事帮你写的初稿,结构清晰,考虑到了常见问题,并且可以直接运行测试。这大大降低了编程的启动门槛,让你能把精力更多集中在问题定义和逻辑设计上,而不是搜索某个API的具体用法或者调试拼写错误。

对于Python开发者,尤其是初学者和希望提升效率的开发者来说,这无疑是一个强大的辅助工具。你可以用它来快速生成数据处理、文件操作、网络请求等常见任务的代码骨架,然后在此基础上进行精细化调整。当然,对于生成的代码,尤其是涉及网络、系统或安全相关的操作,进行人工审查和测试仍然是必不可少的一步。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐