尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Python模块学习路线:从内置模块到pip实战指南

Python模块学习路线:从内置模块到pip实战指南 1. 面向新手的Python模块学习路线先分清为什么学和怎么学很多刚接触Python的朋友一上来就盯着模块两个字发怵总觉得这是一个高深的概念。其实模块没那么玄乎它就是把一组相关的函数、变量、类打包放在一个文件里方便你重复使用。你写了一个文件叫tools.py里面放几个函数那这个文件本身就是一个模块。你平时用的import os、from datetime import datetime本质上就是引入别人写好的模块。这篇文章主要面向两类人一类是刚装好Python、连模块和包都分不清的纯小白另一类是能写简单脚本、但遇到该用什么模块装不上某模块就抓瞎的初学者。我会从模块的分类、常用内置模块、第三方模块的安装、具体项目演练这几个角度把新手最需要的模块知识一次讲透。如果你已经能熟练用requests和pandas了这篇文章对你来说偏基础但里面整理的避坑思路也许能帮你查漏补缺。说句实在话新手学模块最大的误区就是贪多。今天看到这个模块好像有用就装明天听说那个库很火又去装结果环境乱成一锅粥最后连自己写的脚本都跑不起来。所以这篇文章的核心思路是先帮你建立一个模块地图再告诉你每一步实操里会遇到什么坑、怎么绕开。2. 模块到底是什么从文件到命名空间的一次认知升级2.1 先理解模块的基本形态模块最基本的形态就是一个.py文件。比如你新建一个my_math.py里面写两行def add(a, b): return a b def multiply(a, b): return a * b然后在同一个目录下新建main.py写import my_math print(my_math.add(3, 5)) print(my_math.multiply(3, 5))运行main.py就能正常输出结果。这里my_math就是你自己写的模块。如果你运行时报了ModuleNotFoundError: No module named my_math那大概率就是两个文件不在同一个目录下或者你当前运行的目录不对。这里要强调一个新手最容易忽略的点Python 查找模块是按顺序扫描一系列路径的这些路径存在sys.path里。当前脚本所在目录、标准库目录、site-packages存放第三方模块的目录都在内。你想看看自己环境的搜索路径可以运行import sys print(sys.path)看到这个列表你就明白为什么有时候明明装了模块却导入失败了——可能是路径不对也可能是装到了另一个Python环境里。2.2 包和模块的区别目录带来的组织方式当你的模块越来越多比如my_math.py、my_string.py、my_date.py都放在一起会显得很乱。这时你可以建一个目录比如叫myutils然后在目录里放一个空的__init__.py文件这个目录就变成了一个包。myutils/ __init__.py math_tools.py string_tools.py使用的时候from myutils import math_tools print(math_tools.add(1, 2))只要目录里有__init__.pyPython 就会把这个目录当做一个包来对待。即使是空文件也没关系它的存在就是包的标志。这一步新手不用死记只要知道模块是文件包是目录就够了。2.3 为什么模块能避免命名冲突你在自己的代码里定义一个叫open的函数不影响你用import open引入别人写的open模块因为你自己定义的open在全局命名空间而open模块在它自己的命名空间里。这个命名空间隔离的机制就是模块存在的核心价值之一。比如你有两个模块a.py和b.py里面都有read_data函数你可以这样用import a import b a.read_data() b.read_data()两个read_data各干各的互不干扰。新手如果不理解这一点就会遇到那种我导入了一个模块之后为什么我自己的同名函数不好使了的问题。实际原因就是导入操作把模块中的名字引入了当前命名空间覆盖了你原来的定义。3. 新手该优先掌握的内置模块别一上来就扎进第三方库的海洋3.1 os、sys、json 这三大件先吃透os模块负责和操作系统交互比如获取当前目录、创建文件夹、拼接路径。很多新手一上来就学 pathlib但我个人建议先用os因为大量老代码和教程都基于os你读懂老代码再拓展新写法会更容易。import os print(os.getcwd()) # 获取当前工作目录 os.makedirs(test_dir, exist_okTrue) # 创建目录已存在也不报错 print(os.listdir(.)) # 列出当前目录的文件sys模块负责Python解释器相关的操作。最常见的用途是接收命令行参数和查看Python路径import sys args sys.argv print(args)命令行运行python main.py aaa bbbargs就是[main.py, aaa, bbb]。对于写脚本的新手来说这是最朴素的命令行传参方式。json模块负责数据和字符串之间的转换。现在很多接口返回的都是 JSON 格式读写配置文件也常遇到 JSONimport json data {name: python, level: beginner} json_str json.dumps(data, ensure_asciiFalse) print(json_str) with open(config.json, w, encodingutf-8) as f: json.dump(data, f, ensure_asciiFalse, indent2)这里要注意一个细节ensure_asciiFalse是为了让中文不乱码成\uXXXX。新手写 JSON 文件经常遇到中文变乱码的问题罪魁祸首往往就是漏了这个参数。3.2 不要忽视 random、datetime、math 这些小而美的模块random模块是真·宝藏做爬虫模拟请求、写小游戏、做抽样都需要它import random random.randint(1, 10) # 随机整数 random.choice([a, b]) # 随机选择一个元素 random.sample(range(100), 3) # 随机抽3个不重复的datetime模块常见于日志时间戳和日期计算from datetime import datetime, timedelta now datetime.now() print(now.strftime(%Y-%m-%d %H:%M:%S)) yesterday now - timedelta(days1) print(yesterday)math模块提供数学函数比如math.floor(3.7)向下取整、math.ceil(3.2)向上取整。新手写计算相关的脚本会非常常用。我见过不少新手花大量时间研究各种高级库结果真需要算个日期差时反而不会。我的建议是把内置模块当成基本功先练到随手能用再去学requests、pandas、numpy这些第三方库。内置模块是标配第三方库才是选配。3.3 内置模块带来的脚手架思维内置模块某程度上就是一个免费的工具箱。你以为自己在学模块其实是在学如何高效搭一个工具台。我写自动化脚本时经常是几个模块组合着用os处理文件路径、json保存配置、random生成测试数据、datetime记录执行时间。这一套组合拳下来一个像模像样的小工具就出来了。有个小技巧当你感觉自己写的代码重复很多时就停下来想想这个功能是不是可以封装成自己的模块比如你经常要把列表去重后排序就可以写一个my_utils.py把这些常用函数集中放进去。模块化的本质是复用而不是花哨。4. 第三方模块怎么装、怎么选从pip安装到虚拟环境管理4.1 最基础的pip命令装、卸、查第三方模块不在Python安装包里自带需要通过pip安装。打开命令行工具输入pip install requests这里requests是一个发起 HTTP 请求的第三方模块。装完之后在代码里import requests就能正常使用了。一些常用的基础命令pip install numpy # 安装指定模块 pip install numpy1.23.0 # 安装指定版本 pip uninstall numpy # 卸载模块 pip list # 查看所有已安装模块 pip show requests # 查看某个模块的信息新手最容易踩的坑是 pip 和 Python 版本不对应。有些电脑装了多个 Python比如一个 Python3.8 一个 Python3.11你用命令pip install requests装到的模块可能装到了 Python3.8 的环境里但你的代码是用 Python3.11 跑的于是import requests就报错。解决方式是检查对应关系python --version pip --version一般pip --version会提示这个 pip 属于哪个 Python。在 PyCharm 里最好直接在项目设置中指定解释器然后用 PyCharm 的终端来执行 pip 安装这样环境对应关系就不容易错。4.2 遇到安装慢或者失败怎么办国内用户安装第三方模块时官方源经常很慢甚至超时。使用国内镜像源是常见解法以清华源为例pip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple如果每次都要带这一长串参数可以配置默认源。在用户目录下新建或修改pip.iniWindows或pip.confLinux/macOS写入[global] index-url https://pypi.tuna.tsinghua.edu.cn/simple配置完成后再执行 pip 安装就默认走清华源了。还有一种情况是安装某个模块时提示需要编译比如pip install pymssql可能报缺少依赖。这种问题的通用解法是优先找这个模块是否有预编译的wheel包或者去官方文档找Windows安装的专门说明。有些库对Windows用户不友好干脆换一个功能相近的模块这是最省时间的路径。4.3 虚拟环境新手也必须养成的习惯虚拟环境的核心思路是让每个项目有自己独立的模块目录互不干扰。举个例子项目A需要numpy1.21项目B需要numpy1.26如果全部装在同一个全局环境里就会互相冲突。虚拟环境可以避免这种局面。最简单的创建方式python -m venv myenv在Windows下激活方式myenv\Scripts\activate在Linux/macOS下source myenv/bin/activate激活之后命令行前面会显示(myenv)此时再用pip install安装的模块就都装在这个虚拟环境里了。新手可能会觉得麻烦我刚开始学为什么会需要虚拟环境说实话如果只是学语法不装第三方库暂时不用虚拟环境也可以。但一旦开始用requests、pandas这些库做项目虚拟环境能帮你少踩很多坑。特别是你要去跑网上的开源项目时项目自带requirements.txt里面写着一堆依赖你一条命令就能装齐pip install -r requirements.txt要是没有虚拟环境这些依赖就会混进你的全局环境过段时间保准出问题。5. 一个新手最容易上手的模块实战写一个待办事项管理小工具5.1 需求拆解和模块选择与其零散地学模块不如直接做一个小工具把多个模块串起来。我设计了一个最简单的待办事项管理程序功能如下增加待办事项查看所有待办事项删除待办事项数据保存到本地JSON文件下次启动还能读出来涉及到的模块有模块用途json保存和读取待办数据支持中文不乱码os判断数据文件是否存在datetime添加时间戳记录每条待办的创建时间sys处理命令行参数这个项目麻雀虽小五脏俱全能让你一次体验多个模块的配合。而且难度不大新手半天就能写完。5.2 写代码从零实现一个JSON持久化的命令行工具先建一个项目目录todo_app在里面新建todo.py。完整代码如下import os import sys import json from datetime import datetime DATA_FILE todos.json def load_todos(): if not os.path.exists(DATA_FILE): return [] with open(DATA_FILE, r, encodingutf-8) as f: return json.load(f) def save_todos(todos): with open(DATA_FILE, w, encodingutf-8) as f: json.dump(todos, f, ensure_asciiFalse, indent4) def add_todo(content): todos load_todos() todos.append({ id: len(todos) 1, content: content, created_at: datetime.now().strftime(%Y-%m-%d %H:%M:%S) }) save_todos(todos) print(f已添加: {content}) def list_todos(): todos load_todos() if not todos: print(当前没有待办事项) return for item in todos: print(f#{item[id]} - {item[content]} - {item[created_at]}) def delete_todo(todo_id): todos load_todos() new_todos [item for item in todos if item[id] ! todo_id] if len(new_todos) len(todos): print(f没有找到 id{todo_id} 的待办事项) return save_todos(new_todos) print(f已删除 id{todo_id}) if __name__ __main__: if len(sys.argv) 2: print(用法: python todo.py add 内容 / list / delete id) sys.exit(1) command sys.argv[1] if command add: if len(sys.argv) 3: print(请提供待办事项内容) else: add_todo(sys.argv[2]) elif command list: list_todos() elif command delete: if len(sys.argv) 3: print(请提供要删除的待办事项id) else: delete_todo(int(sys.argv[2])) else: print(未知命令支持 add / list / delete)这段代码虽然不长但每个模块都在实际干活。os.path.exists判断文件json.dump序列化写入json.load反序列化读取datetime.now().strftime格式化时间sys.argv接收命令行参数。如果你能不看注释把这个程序从头到尾自己敲一遍再改一改功能那你对模块配合的理解会上一个台阶。5.3 实操过程中的几个窍门和小坑第一id的生成方式比较粗糙用len(todos) 1来生成删除最后一条后再添加会出现 id 重复。但如果只是学模块这个简化设计完全可以接受。真要做到严谨需要用一个自增计数器或者用时间戳当id。第二写 JSON 文件时一定记得encodingutf-8和ensure_asciiFalse。否则你在命令行里输出的中文、写入文件的中文都会变成乱码。第三if __name__ __main__:这一行要理解。它表示只有当这个文件被直接运行时下面的代码才会执行。如果这个文件被其他模块导入这段不会跑。新手写模块的时候养成这个习惯后面用起来会很舒服。我在实际调试中经常遇到的情况是程序运行一遍之后想再运行一遍数据文件里已经有上次的旧数。这时你要是手动打开todos.json修改很容易改坏格式。所以调试时建议python todo.py add 学习模块 python todo.py add 写总结 python todo.py list python todo.py delete 1这样一个一个命令敲能清楚看到每一步数据变化。6. 模块学习的常见报错和问题排查这些坑我都替你踩过6.1 ModuleNotFoundError 是最常见的错误这个报错在刚学模块时出现的频率几乎每天都能遇到。新手第一反应往往是模块没装好但实际上原因可能有好几种模块确实没有安装、安装了但装到了别的Python环境、文件名和导入名不一致、当前目录不对导致Python找不到你的文件。排查顺序我建议这样做检查模块是否安装pip show 模块名检查安装到了哪个环境pip --version和python --version是否对应在当前Python环境中试一下import 模块名确认能不能导入如果是自己写的模块检查文件名是不是写错了以及这个文件是否在当前目录或sys.path路径下有一个小技巧把下面这条命令记住能解决很多问题python -m pip install 模块名用python -m pip可以确保用当前活着的Python环境对应的pip去安装比直接输pip靠谱得多。6.2 ImportError 和 AttributeError 的区别ImportError是导入时出问题AttributeError是导入成功但访问了一个模块里不存在的属性。比如import json print(json.dumpsx({})) # AttributeError: module json has no attribute dumpsx这种报错很容易排查一般是你把函数名记错了。解决办法是去查文档或者用dir(json)看看模块里到底有哪些可用属性。import json print([name for name in dir(json) if not name.startswith(_)])这个方法可以帮你快速了解一个模块对外暴露了哪些接口我觉得比查文档还直观。6.3 安装第三方模块时提示requires a different Python version有些库的最新版只支持特定Python版本。比如你的Python是3.8某个模块已经停止支持3.8了pip 就会报错。这时候最简单的办法是安装旧版本pip install 模块名版本号去找合适的版本号可以通过pip index versions 模块名看到可用版本列表后再挑一个或者去这个模块的 PyPI 页面查它的版本兼容说明。这是我个人最常用的方法。很多人一看到这种报错就慌了觉得必须升级Python。其实很多时候装个旧版本就能解决问题而且对你的学习项目来说完全够用。6.4 关于模块学习的最终建议先会用再理解原理模块学习不要求你把底层源码读透。你用requests发请求不需要先把 HTTP 协议完全搞懂你用pandas处理数据也不需要先把数据帧的内部实现背下来。但你至少要知道这个模块解决什么问题、怎么安装、有没有文档、常见用法是什么。对新手的模块学习我自己有一个三步走的方法看官方文档的快速入门部分把例子跑通找一个实际小项目用这个模块解决一个小问题遇到不懂的去翻源码或看社区讨论就拿json来说我见过太多人只会在交互式环境里json.dumps打印一下却不会配合文件读写做持久化。这就是典型的知道API但没做过项目。你动手写一遍待办事项工具对所有相关模块的理解都会立刻立体起来。模块这东西说难不难说简单也不简单。难在你可能一时不知道有哪些模块、该选哪个简单在只要你动手做一个项目这些疑问会自然消失。希望这篇文章能把你的模块地图建起来接下来多敲代码、多碰壁、多解决问题你很快会发现模块其实就是你编程路上的一个个工具箱随取随用常换常新。
返回列表