✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨
🎯 你正在阅读「Python 从零摸索日记」系列文章 🎯
✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨
🔥 弹简特 个人主页
❄️ 个人专栏直通车:
✨ 靠热爱去书写自己,靠勇敢去书写生活!
✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨
🌟 博主简介:

文章目录:
- 一、前言
- 二、模块、包、库
-
- 1、概念
-
- [1.1 模块](#1.1 模块)
- [1.2 包](#1.2 包)
- [1.3 库](#1.3 库)
- 2、导入模块的常用方式
-
- [2.1 方式1:`import 模块名`](#2.1 方式1:
import 模块名) - [2.2 方式2:`from 模块名 import 函数名/变量名`](#2.2 方式2:
from 模块名 import 函数名/变量名) - [2.3 方式3:`from 模块名 import *`](#2.3 方式3:
from 模块名 import *) - [2.4 给模块或函数起别名(`as`)](#2.4 给模块或函数起别名(
as))
- [2.1 方式1:`import 模块名`](#2.1 方式1:
- 3、自定义模块的创建和导入
-
- [3.1 创建自定义模块](#3.1 创建自定义模块)
- [3.2 导入自定义模块](#3.2 导入自定义模块)
- 4、自定义包的创建和导入
-
- [4.1 创建包的结构](#4.1 创建包的结构)
- [4.2 导入包中的模块](#4.2 导入包中的模块)
- [4.3 关于 `init.py` 的作用](#4.3 关于
__init__.py的作用)
- 5、注意事项和常见错误
-
- [5.1 命名规则](#5.1 命名规则)
- [5.2 导入路径问题](#5.2 导入路径问题)
- [5.3 循环导入](#5.3 循环导入)
- [5.4 `import` 和 `from ... import ...` 的区别](#5.4
import和from ... import ...的区别)
- 三、异常处理
- 四、文件操作
-
- 1、操作文件的三个步骤
- 2、文件的打开模式
- [3、读取文件内容(`read`, `readlines`, `readline`)](#3、读取文件内容(
read,readlines,readline)) - [4、写入文件(`w` 覆盖,`a` 追加)](#4、写入文件(
w覆盖,a追加)) - 5、二进制文件操作(图片、音频等)
- 6、文件常用操作(删除文件、删除文件夹)
-
- [6.1 删除文件](#6.1 删除文件)
- [6.2 删除文件夹](#6.2 删除文件夹)
- [6.3 获取指定目录文件列表](#6.3 获取指定目录文件列表)
- [6.4 修改文件名和文件](#6.4 修改文件名和文件)
- [6.5 获取当前文件的路径信息](#6.5 获取当前文件的路径信息)
- [6.6 创建一个文件夹](#6.6 创建一个文件夹)
- 五、写在最后
一、前言
老铁们,本文带你理清模块、包、库的层级关系,掌握导入技巧、异常捕获与文件操作。从零实战,轻松跨越新手进阶门槛。
二、模块、包、库
1、概念
1.1 模块
一句话解释 :
一个 .py 文件就是一个模块。模块里可以写变量、函数、类等。

生活类比 :
模块就像一本"菜谱"的其中一页。这一页专门记录"鱼香肉丝"的做法(变量、函数、类等)。
例子 :
你新建一个文件叫 tools.py,里面写:
python
# tools.py 这个文件就是一个模块
name = "计算器"
def add(a, b):
return a + b
def multiply(a, b):
return a * b
这个 tools.py 就是一个模块。

1.2 包
一句话解释 :
一个包含多个 .py 模块的文件夹,并且这个文件夹里必须有一个 __init__.py 文件(可以是空的),这个文件夹就叫做包。
生活类比 :
包就像一个"菜谱文件夹",里面有好多页(模块),每页一个菜。__init__.py 就像文件夹的封面,标记这是一个包。
例子:
bash
my_package/ # 这是一个包(文件夹)
__init__.py # 必须存在(可以是空文件)
math_tools.py # 模块1
string_tools.py # 模块2


1.3 库
一句话解释 :
库是一个更大的概念,通常指多个包集合在一起 ,提供一系列相关功能。比如 Python 标准库(os、sys、random 等)、第三方库(requests、numpy、pandas)。
生活类比 :
库就像一个"大图书馆",里面有好多菜谱文件夹(包),还有很多其他功能的书。
注意 :
在口语中,可能很多人会把"模块"、"包"、"库"混用,但我们得要知道它们层级关系:
模块(一个文件) < 包(一个文件夹+多个文件) < 库(多个包)
2、导入模块的常用方式
Python 有很多自带的模块(标准库),不需要安装,直接 import 就能用。
2.1 方式1:import 模块名
使用格式:模块名.函数名() 或 模块名.变量名
例子 :使用 random 模块生成随机数
python
import random
num = random.randint(1, 10) # 生成1到10之间的随机整数
print(num)

2.2 方式2:from 模块名 import 函数名/变量名
这样导入后,可以直接用函数名,不需要加模块名前缀。
python
from random import randint
num = randint(1, 10) # 直接写函数名
print(num)

导入多个方法或者变量 :from random import randint, choice, shuffle

2.3 方式3:from 模块名 import *
导入模块中的所有内容(不推荐,容易命名冲突)。
python
from random import *
num = randint(1, 10)
print(choice(["苹果", "香蕉"]))

2.4 给模块或函数起别名(as)
当模块名太长,或者你自己想换个名字,用 as 取别名。
python
import random as r
num = r.randint(1, 10) # 用别名 r
print(num)

也可以给函数起别名:
python
from random import randint as ri
num = ri(1, 10)
print(num)

注意 :原名 randint 失效,只能用新名字 ri。
3、自定义模块的创建和导入
3.1 创建自定义模块
假设在当前目录下新建一个文件 mymodule.py,里面写:
python
# mymodule.py
name = "张三"
def say_hello():
print("你好,我是自定义模块的函数")

3.2 导入自定义模块
在同一目录下新建一个文件 main.py,然后导入 mymodule:
方式1:import 模块名
python
import mymodule
print(mymodule.name) # 输出:张三
mymodule.say_hello() # 输出:你好,我是自定义模块的函数

方式2:from 模块名 import 变量/函数
python
from mymodule import name, say_hello
print(name) # 直接使用变量
say_hello() # 直接调用函数

方式3:from 模块名 import *
python
from mymodule import *
print(name)
say_hello()

注意:Python 导入模块时,会执行模块中的代码(比如打印语句、定义函数等)。但一般模块里只放定义,不放主动执行的代码(除了测试)。
4、自定义包的创建和导入
4.1 创建包的结构
假设我们想创建一个包叫 mypackage,里面有两个模块:module_a.py 和 module_b.py。
步骤:
- 新建一个文件夹,叫
mypackage。 - 在文件夹里新建一个空文件
__init__.py(Python 识别包必须要有这个文件,可以是空的)。 - 在文件夹里新建
module_a.py和module_b.py。
文件夹结构:
bash
当前目录/
├── main.py # 我们用来测试导入的文件
└── mypackage/ # 这是一个包
├── __init__.py # 空文件
├── module_a.py
└── module_b.py

module_a.py 内容:
python
# module_a.py
name_a = "模块A"
def func_a():
print("我是模块A的函数")
module_b.py 内容:
python
# module_b.py
name_b = "模块B"
def func_b():
print("我是模块B的函数")
4.2 导入包中的模块
在 main.py 中,你可以用以下几种方式导入:
方式1:导入整个模块(需要加包名.模块名)
python
import mypackage.module_a
print(mypackage.module_a.name_a)
mypackage.module_a.func_a()
方式2:from 包名 import 模块名
python
from mypackage import module_a
print(module_a.name_a)
module_a.func_a()
方式3:from 包名.模块名 import 具体内容
python
from mypackage.module_a import name_a, func_a
print(name_a)
func_a()
方式4:from 包名.模块名 import *
python
from mypackage.module_a import *
print(name_a)
func_a()
4.3 关于 __init__.py 的作用
__init__.py。它的作用:
- 告诉 Python 这个文件夹是一个包,可以被导入。
- 可以在里面写代码,当你
import mypackage时会自动执行。 - 可以控制
from mypackage import *会导入哪些模块(通过定义__all__列表)。
通常我们初学者可以暂时只放一个空文件。
5、注意事项和常见错误
5.1 命名规则
模块名、包名、变量名、函数名都要符合标识符命名规则:
字母、数字、下划线组成,不能数字开头,不能是关键字(如 if、for、import),区分大小写。
5.2 导入路径问题
Python 查找模块的路径包括:
- 当前脚本所在目录
- 环境变量
PYTHONPATH - 标准库路径
- 第三方库安装路径
如果自定义模块不在当前目录,需要添加路径或用相对导入(以后讲)。
5.3 循环导入
不要出现 a.py 导入 b.py,同时 b.py 又导入 a.py,会导致错误。
例如:

5.4 import 和 from ... import ... 的区别
import 模块名:需要写模块名.xxx,不会污染当前命名空间。from 模块名 import xxx:直接使用xxx,但如果有同名变量会覆盖。
推荐:一般用 import 模块名 更清晰;只导入少数常用函数时可以用 from ... import ...。
三、异常处理
1、什么是异常?
一句话解释 :
你写的代码在运行时发生了错误(比如变量没定义、除以零、文件不存在),Python 就会"抛出一个异常",程序会崩溃并打印一堆红色错误信息。
生活类比 :
你让朋友去拿"冰箱里的蛋糕",但冰箱里根本没有蛋糕。朋友就会回来跟你说"没有蛋糕啊!"------这个"没有蛋糕"就是异常。
最简单的异常例子:
python
print(a) # a 这个变量没定义过
运行后你会看到类似这样的信息:

Traceback:异常追溯,告诉你错误发生的路径。File "xxx", line 1:哪个文件的第几行。NameError: name 'a' is not defined:异常类型和具体原因。
这些异常信息构造 就是告诉你:异常信息包括执行路径 、文件行号 、错误类型和原因。看懂这些信息就能快速定位 bug。
2、怎么捕获异常?(try-except-else-finally)
如果你的程序可能因为用户输入错误、文件不存在等发生异常,你不想让程序崩溃 ,而是想"优雅地处理"这个错误(比如提示用户重新输入),这时就用 try...except。
基本结构:
python
try:
# 这里放可能会出错的代码
except:
# 如果 try 中出了异常,就执行这里的代码(程序不会崩溃)
else:
# 如果 try 中没有出异常,就执行这里的代码(可选)
finally:
# 不管有没有异常,最后都会执行这里的代码(可选,常用于关闭文件、释放资源)
例如:
python
try:
print("开始尝试执行代码")
num = int(input("请输入一个数字:")) # 如果用户输入的不是数字,会触发 ValueError
result = 10 / num # 如果用户输入 0,会触发 ZeroDivisionError
print("计算结果是:", result)
except:
print("出错了!可能是输入的不是数字,或者除以了零。")
else:
print("没有发生异常,恭喜!")
finally:
print("不管有没有异常,我都会执行。")
执行情况模拟:
-
用户输入
5(正常)→ 输出:开始尝试执行代码 计算结果是: 2.0 没有发生异常,恭喜! 不管有没有异常,我都会执行。
-
用户输入
0(除以零)→ 输出:开始尝试执行代码 出错了!可能是输入的不是数字,或者除以了零。 不管有没有异常,我都会执行。
-
用户输入
abc(不是数字)→ 输出类似上面。
关键点:
try中一旦发生异常,立刻跳转到except,try中剩余代码不再执行。except只捕获异常,不解决异常根源(只是让你有机会做补救措施,比如提示重新输入)。else只有在try完全没异常时才执行。finally无论如何都执行,非常适合做清理工作(比如关闭文件)。
3、捕获特定类型的异常
上面的 except: 会捕获所有 异常,但有时候你想针对不同异常做不同处理,可以写多个 except。
python
try:
num = int(input("输入数字:"))
result = 10 / num
except ValueError:
print("你输入的不是合法数字!")
except ZeroDivisionError:
print("不能除以零!")
except Exception as e: # 捕获其他所有异常,e 是异常对象
print("未知错误:", e)
else:
print("结果是", result)
finally:
print("结束")
建议 :写代码时先不要加 try,先让程序崩溃,看清楚是什么异常类型(比如 ValueError、ZeroDivisionError),然后再用对应的 except 去捕获它。
4、异常的传递
一句话解释 :
如果函数 A 调用函数 B,函数 B 调用函数 C,在 C 中发生了异常且没有捕获,那么这个异常会一层一层往外传 ,直到被某个 try...except 捕获,如果一直没捕获,程序就崩溃。

例子:
python
def func1():
print("func1 开始")
func2() # 调用 func2
def func2():
print("func2 开始")
print(x) # x 没定义,会触发 NameError
def main():
try:
func1()
except NameError:
print("捕获到了 NameError,程序没有崩溃")
main()
输出:
func1 开始
func2 开始
捕获到了 NameError,程序没有崩溃

关键点:
- 异常会沿着调用链往回传递,直到被
try...except接住。 - 如果最外层也没接,程序就崩溃并打印 Traceback(那个红色错误信息)。
- 利用这个特性,你可以在合适的地方统一处理异常 ,而不是每个函数内部都写
try。
四、文件操作
1、操作文件的三个步骤
- 打开文件 :
open(文件路径, 模式, encoding='编码') - 读/写文件 :
.read()、.write()、.readlines()等 - 关闭文件 :
.close()(释放系统资源)
生活类比 :
打开冰箱(打开文件),拿一瓶饮料(读或写),关上冰箱门(关闭文件)。不关门的话,冰箱会一直耗电(占用系统资源)。
2、文件的打开模式
| 模式 | 含义 | 文件不存在时 |
|---|---|---|
'r' |
只读(默认) | 报错 FileNotFoundError |
'w' |
只写,会覆盖原有内容 | 创建新文件 |
'a' |
追加,在文件末尾写入 | 创建新文件 |
'rb' |
二进制只读(图片、视频等) | 报错 |
'wb' |
二进制只写,会覆盖 | 创建新文件 |
'ab' |
二进制追加 | 创建新文件 |
注意 :文本文件(.txt)一般指定 encoding='utf-8',二进制文件(图片、音频)不能 指定 encoding。
3、读取文件内容(read, readlines, readline)
假设有一个 test.txt 文件,内容为:
你好,这里是
零基础学Python园地

方法1:.read() --- 一次性读取全部内容(字符串)
python
file = open('text.txt', 'r', encoding='utf-8')
content = file.read()
print(content) # 输出两行文字
file.close()

方法2:.readlines() --- 一次性读取全部,按行返回列表(每行末尾有 \n)
python
file = open('text.txt', 'r', encoding='utf-8')
lines = file.readlines()
print(lines) # 输出:['你好,这里是\n', '零基础学Python园地']
# 去除换行符
print('--'*100)
# 首先使用一个列表,到时候存储去除换行之后的数据
clean_lines = []
# 遍历返回的lines
for i in lines:
clean_lines.append(i.strip())
print(clean_lines) # 输出:['你好,这里是', '零基础学Python园地']
file.close()


方法3:.readline() --- 一次读取一行,多次调用读取下一行
python
file = open('text.txt', 'r', encoding='utf-8')
line1 = file.readline() # 第一行
line2 = file.readline() # 第二行
print(line1, end='') # 不额外加换行
print(line2, end='')
file.close()

注意 :.read() 和 .readlines() 适合小文件;大文件建议用循环 .readline() 或直接 for line in file:。
4、写入文件(w 覆盖,a 追加)
覆盖写入 ('w') :
文件存在则清空原内容,不存在则新建。
python
file = open('output.txt', 'w', encoding='utf-8')
file.write("第一行\n") # \n 表示换行
file.write("第二行")
file.close()

追加写入 ('a') :
在文件末尾追加内容,不覆盖原有内容。
python
file = open('output.txt', 'a', encoding='utf-8')
file.write("\n新增的一行")
file.close()

5、二进制文件操作(图片、音频等)
不能直接 'r' 或 'w' 去读写图片,因为图片是二进制数据。要用 'rb'(读二进制)和 'wb'(写二进制)。
例子:复制图片

接下来使用文件的读取加写入,将这个文件拷贝一份到output目录下,注意前提得先有output这个目录


代码如下:
python
# 打开原图(二进制读)
# 打开原图(二进制读)
with open('srcpic/1.jpg', 'rb') as src:
data = src.read()
# 写入新文件(二进制写)
with open('output/1_copy.jpg', 'wb') as dst:
dst.write(data)
解释疑问: 为什么第二个中可以使用第一个的局部变量?
只有函数、类、模块才会创建新的作用域 。像 with、if、for、while 这些语句块,不会创建独立的作用域。
所以,你在第一个 with 块里定义的变量 data,其实是属于它所在的函数或全局作用域。第二个 with 块自然也能访问到它。
结果:

什么是 with open(...) as 变量:?
这叫"上下文管理器",它会在代码块执行完后自动关闭文件 ,即使中间发生异常也会关闭。你就不需要手动写 .close() 了,非常推荐使用。
用法:
python
with open('rap.txt', 'r', encoding='utf-8') as f:
content = f.read()
# 这里文件已经自动关闭,不需要 f.close()
6、文件常用操作(删除文件、删除文件夹)
需要导入 os 和 shutil 模块。
- 删除文件 :
os.remove('文件路径') - 删除空文件夹 :
os.rmdir('文件夹路径')(只能删空的) - 删除非空文件夹(递归删除,慎用!) :
shutil.rmtree('文件夹路径')
python
import os
import shutil
# 删除单个文件
os.remove('test.txt')
# 删除空文件夹
os.rmdir('empty_folder')
# 删除非空文件夹(危险,删了找不回)
shutil.rmtree('not_empty_folder')
注意 :shutil.rmtree 非常危险,没有回收站功能,生产环境慎用。
6.1 删除文件
使用:os.remove(文件目录)
py
# 文件的删除
import os
os.remove('output.txt')

6.2 删除文件夹
py
# 删除文件夹
import os
import shutil
# 删除一个空的文件夹使用的是rmdir
os.rmdir('111')
# 删除一个非空的文件夹使用 rmtree
shutil.rmtree('output')
6.3 获取指定目录文件列表
使用:os.listdir(目录)
py
import os
# 获取指定的目录文件列表
list_dir = os.listdir(r"E:\python_project\basic-python-grammar-learning\PythonBasicGrammar")
# 返回的是列表
print(list_dir)
print(f'列表中每一个元素是字符串:{type(list_dir[0])}')

如果路径中出现了转义字符,那么我们就在字符串前面加一个r


6.4 修改文件名和文件
py
import os
# 修改文件名
os.rename('tools.py', 'tool.py')
# 修改目录名
os.rename('srcpic', 'des')
6.5 获取当前文件的路径信息
py
# 获取当前文件的路径信息:绝对路径
import os
print(os.getcwd())
6.6 创建一个文件夹
py
# 创建一个文件夹
import os
os.mkdir('111')
五、写在最后
能坚持看到最后的朋友,属实是真爱学编程了,先歇会儿眼睛放松一下~
很多同学刚开始学Python,都不知道它到底能干啥。还是简单跟大伙唠唠:
可以做自动化测试 、写办公脚本解放双手 、爬虫采集数据 、做数据分析、开发小工具、甚至做简单后端和小游戏,用途真的特别广。
最后分享几句实在又走心的话送给正在学Python的你:
慢慢来别着急,代码不会辜负每一个愿意坚持敲键盘的人。
现在多学一点技能,未来就多一份选择的底气。
与其原地迷茫焦虑,不如从一行Python代码开始悄悄变强。
看似不起眼的日复一日,终会在将来的某天,让你看到坚持的意义。
铁汁们~ 觉得内容有用的话,麻烦点个赞、关注一波,后续会持续更新Python入门、实战、自动化相关笔记,咱们一起慢慢进阶。
文章有哪里讲得不妥的,欢迎评论区随时指正,大家一起交流进步!
兄弟们,咱们一起学好Python,悄悄逆袭~~~

