导入模块的一个就是
python
from 模块 import 功能
1. time 模块
一般使用 time模块就是让程序休息几秒或者计算时间差。
python
import time
# 简单的计算系统差值
# 当前系统时间, 从1970年1月1日0点0分0秒开始到现在经过了多少秒
before_time = time.time()
print(f"before_time = {before_time}")
time.sleep(1)
current_time = time.time()
print(f"current_time = {current_time}")
输出结果:
before_time = 1784248413.4519768
current_time = 1784248414.4528716
2. datetime 模块
后面处理时间的时候经常会使用datetime模块来进行处理
python
from datetime import datetime
# 当前系统时间
current_sysytem_time = datetime.now()
print(f"current_sysytem_time = {current_sysytem_time}")
# 时间格式化
print(f"格式化后的 current_sysytem_time = {current_sysytem_time.strftime('%Y-%m-%d %H:%M:%S')}")
# 字符串转化成时间
# 这里容易出现格式不匹配的错误,所以需要 try-except 一下
try:
str_date = input("请输入一个时间(格式 yyyy-mm-dd HH:MM:SS):")
d = datetime.strptime(str_date, "%Y-%m-%d %H:%M:%S")
print(d)
print(type(d))
except Exception as e:
print(f"出现了错误 e = {e}")
输出结果:
current_sysytem_time = 2026-07-17 08:31:35.962242
格式化后的 current_sysytem_time = 2026-07-17 08:31:35
请输入一个时间(格式 yyyy-mm-dd HH:MM:SS):2026-07-17 08:31:55
2026-07-17 08:31:55
<class 'datetime.datetime'>
常用的格式化标准:
python
%y 两位数的年份表示(00-99)
%Y 四位数的年份表示(000-9999)
%m 月份(01-12)
%d 月内中的一天(01-31)
%H 24小时制小时数(0-23)
%I 12小时制小时数(01-12)
%M 分钟数(00=59)
%S 秒(00-59)
3. random 模块
python 中专门生成随机数的一个模块
python
import random
# 生成 0-1 的是随机数
num = random.random()
print(f"0-1的随机数 num = {num}")
print(type(num))
# 随机小数(10, 20) 返回 10-20 之间的随机浮点数
random_decimal = random.uniform(10, 20)
print(f"随机小数 random_decimal = {random_decimal}")
# 随机整数 [50, 60]
random_int = random.randint(50, 60)
print(f"随机整数 random_int = {random_int}")
# 以列表操作举一个例子
lst = ['hello', 'world', 'i', 'am', 'lili']
# 从列表中随机选择一个
random_lst = random.choice(lst)
# 从列表中随机选取n个
some = random.sample(lst, 3)
print(some)
# 打乱一个列表
random.shuffle(lst)
print(lst)
输出结果:
0-1的随机数 num = 0.8742667760337914
<class 'float'>
随机小数 random_decimal = 11.047373723323254
随机整数 random_int = 60
['hello', 'i', 'lili']
['am', 'lili', 'world', 'i', 'hello']
4. pickle 模块
pickle是一种可以把python对象写入到文件中的解决方法,但是写入到文件中的内容是bytes,就是把python对象转换为字节的过程,也就是序列化。
python
import pickle
lst = ['你好', '你很好']
# 把一个对象转换为字节(序列化)
dump_res = pickle.dumps(lst)
print("dump_res = ", dump_res)
# 把一个数据转换为字节,并且写入到文件中去
pickle.dump(lst, open("lst.dat", mode='wb'))
# 从文件中读取原来的二进制数据转换为原来的数据,就是反序列化
lst = pickle.load(open("lst.dat", mode='rb'))
origin_res = pickle.loads(dump_res)
print("origin_res = ", origin_res)
# 输出结果:
dump_res = b'\x80\x05\x95\x1a\x00\x00\x00\x00\x00\x00\x00]\x94(\x8c\x06\xe4\xbd\xa0\xe5\xa5\xbd\x94\x8c\t\xe4\xbd\xa0\xe5\xbe\x88\xe5\xa5\xbd\x94e.'
origin_res = ['你好', '你很好']
5. json 模块
在前后端交互的过程中,数据基本都是通过json来进行交互的。因为json可以完美的演绎出一个对象
python
import json
dic = {'a': '张三', 'b': '李四', 'c': '王五'}
# 把字典转换为json字符串
json_str = json.dumps(dic)
print(json_str) # 输出结果:{"a": "\u5f20\u4e09", "b": "\u674e\u56db", "c": "\u738b\u4e94"}
print("type(json_str) = ", type(json_str))
# 上面输出的json字符串并不友好,所以可以设置 ensure_ascii = False
chinese_json_str = json.dumps(dic, ensure_ascii=False)
print(chinese_json_str) # 输出结果:{"a": "张三", "b": "李四", "c": "王五"}
print("type(chinese_json_str) = ", type(chinese_json_str))
# 将json字符串转换为字典
str_dic = '{"a":"张三", "b":"李四", "c":"王五"}'
dic = json.loads(str_dic)
print(f"type(dic) = {type(dic)}, dic = {dic}") # 输出结果:type(dic) = <class 'dict'>, dic = {'a': '张三', 'b': '李四', 'c': '王五'}
# json也可以像pickle一样可以序列化结果然后写入到文件中去
f = open("test.json", mode="w", encoding="utf-8")
json.dump(dic, f, ensure_ascii=False)
f.close()
# 同时也可以从文件中读取一个json
f = open("test.json", mode="r", encoding="utf-8")
dic = json.load(f)
f.close()
print(f"type(dic) = {type(dic)}, dic = {dic}") # 输出结果:type(dic) = <class 'dict'>, dic = {'a': '张三', 'b': '李四', 'c': '王五'}
6. hashlib 模块
md5是一个不可逆的加密算法,在python中我们只需要引入hashlib的模块就可以了
python
import hashlib
md5_str = hashlib.md5()
md5_str.update("hello world".encode("utf-8"))
print("md5_str = ", md5_str.hexdigest()) # 输出结果:md5_str = 5eb63bbbe01eeed093cb22bb8f5acdc3
# 但是,现在有很多的原始算法已经公开了,所以用原始的可能会出现暴露的风险。所以可以加盐来增加安全性
obj = hashlib.md5(b"i like python")
obj.update("hello world".encode("utf-8"))
print("obj = ", obj.hexdigest()) # 输出结果:obj = 5ccc35170836388785ae1ca3a8e52604
7. shutil 模块
shutil主要封装了文件和文件夹相关的操作,比如文件赋值粘贴,文件移动,文件夹的复制、移动等等
注:linux和mac中可以使用ls-all 查看文件夹内所有文件的权限和修改时间,在windows中使用dir命令查看相关的内容
python
import shutil
fsrc = open("a.txt", "rb")
fdst = open("b.txt", "wb")
# 拷贝文件对象,设置10kb的缓冲区
shutil.copyfileobj(fsrc, fdst, 1024*10)
# 拷贝文件,直接给出路径就是了
shutil.copyfile("a.txt", "b.txt")
shutil.copymode("a.txt", "e.txt")
# 把访问权限拷贝
shutil.copymode(".", "e.txt")
# 把权限, 访问时间, 修改时间等信息拷贝
shutil.copystat(".", "d.txt")
# copyfile() + copymode()
shutil.copy("dir/a.txt", "dir/f.txt")
# copyfile() + copystat()
shutil.copy2("dir/a.txt", "dir/f.txt")
# 拷贝文件夹
shutil.copytree("./dir", "./baby")
# 删除文件夹
shutil.rmtree("dir")
# 移动文件, 如果dst文件目录不存在. 则重命名src文件
shutil.move(src, dst)
8. logging 模块
Python 的 logging 模块是一个非常强大且标准化的日志记录工具,它远比简单的 print() 灵活和健壮。
python
import logging
# ---------- 基础配置 ----------
# filename: 日志文件路径(不指定则输出到控制台)
# filemode: 文件写入模式,'a'=追加(默认),'w'=覆盖
# format: 日志格式模板
# datefmt: 时间格式(符合 time.strftime 规范)
# level: 全局日志阈值,只有级别 >= 该值的日志才会被记录
logging.basicConfig(
filename='app_basic.log', # 日志文件名
filemode='a', # 追加模式
format='%(asctime)s | %(levelname)-8s | %(filename)s:%(lineno)d | %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
level=logging.DEBUG # 记录所有级别的日志
)
# ---------- 记录不同级别的日志 ----------
# 级别从低到高:DEBUG < INFO < WARNING < ERROR < CRITICAL
logging.debug("这是 DEBUG 级别 - 用于详细的调试信息")
logging.info("这是 INFO 级别 - 用于程序正常运行的信息")
logging.warning("这是 WARNING 级别 - 表示潜在问题,但程序继续运行")
logging.error("这是 ERROR 级别 - 表示发生错误,某些功能失败")
logging.critical("这是 CRITICAL 级别 - 表示严重错误,程序可能崩溃")
# ---------- 使用 logging.log() 自定义级别 ----------
# 第一个参数是级别数值,第二个是消息
# 注意:自定义级别可能会破坏规范,一般不建议使用
logging.log(25, "这是自定义级别 25(介于 INFO 和 WARNING 之间)")
多子系统日志分离示例 场景:一个大项目中有两个子系统(A和B),需要将日志分开记录.原有的basicConfig就不行了。需要用到FileHandler,来完成日志的分开记录。
python
# ---------- 子系统 A ----------
# 1. 创建 FileHandler(负责写文件)
# 参数:filename, mode, encoding
handler_a = logging.FileHandler(
'system_a.log', # 日志文件名
mode='a', # 'a'=追加, 'w'=覆盖
encoding='utf-8' # 避免中文乱码
)
# 2. 设置格式(每个子系统可以有自己独立的格式)
formatter_a = logging.Formatter(
fmt='%(asctime)s | %(name)-10s | %(levelname)-8s | %(filename)s:%(lineno)d | %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
handler_a.setFormatter(formatter_a)
# 3. 创建 Logger(使用独立的名称)
# 注意:使用 logging.getLogger() 而不是 logging.Logger()
# 这样可以充分利用 logging 模块的层级管理
logger_a = logging.getLogger('SystemA') # 推荐方式
# 或者:logger_a = logging.Logger('SystemA') # 不推荐,会绕过 logging 的管理
logger_a.setLevel(logging.DEBUG) # 设置级别
logger_a.addHandler(handler_a) # 添加处理器
# ---------- 子系统 B ----------
handler_b = logging.FileHandler(
'system_b.log',
mode='a',
encoding='utf-8'
)
# B 使用不同的格式(可以显示更多信息)
formatter_b = logging.Formatter(
fmt='%(asctime)s | %(name)-10s | %(levelname)-8s | %(filename)s:%(lineno)d | %(funcName)s() | %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
handler_b.setFormatter(formatter_b)
logger_b = logging.getLogger('SystemB')
logger_b.setLevel(logging.DEBUG)
logger_b.addHandler(handler_b)
# ---------- 测试 ----------
# 子系统 A 的日志
logger_a.debug("系统A:调试信息(不会写入文件,因为被注释了)")
logger_a.info("系统A:用户登录成功")
logger_a.warning("系统A:磁盘空间不足 80%")
logger_a.error("系统A:数据库连接失败")
logger_a.critical("系统A:系统即将崩溃")
# 子系统 B 的日志
logger_b.info("系统B:服务启动成功")
logger_b.warning("系统B:API 响应缓慢")
logger_b.error("系统B:处理请求时发生异常", exc_info=True)
# ---------- 问题演示:日志会重复吗? ----------
# 注意:root logger 默认会记录 INFO 及以上级别的日志到控制台
# 如果你同时配置了 root logger,可能会导致日志重复
# 解决方法:禁用 propagate
logger_a.propagate = False # 不传播到父 Logger
logger_b.propagate = False
| 字段 | 含义 | 示例值 | 重要程度 |
|---|---|---|---|
%(asctime)s |
日志记录时间 | 2026-07-27 15:30:45 | ⭐⭐⭐⭐⭐ |
%(name)s |
Logger 名称 | my_app.system_a | ⭐⭐⭐⭐⭐ |
%(levelname)s |
日志级别名称 | INFO | ⭐⭐⭐⭐⭐ |
%(levelno)s |
日志级别数值 | 20 | ⭐⭐⭐ |
%(message)s |
日志消息内容 | 用户登录成功 | ⭐⭐⭐⭐⭐ |
%(filename)s |
源文件名 | main.py | ⭐⭐⭐⭐ |
%(pathname)s |
源文件完整路径 | /home/user/main.py | ⭐⭐⭐ |
%(module)s |
模块名(不含扩展名) | main | ⭐⭐⭐⭐ |
%(funcName)s |
函数名 | login_user | ⭐⭐⭐⭐ |
%(lineno)d |
行号 | 42 | ⭐⭐⭐⭐⭐ |
%(process)d |
进程ID | 12345 | ⭐⭐⭐ |
%(processName)s |
进程名称 | MainProcess | ⭐⭐⭐ |
%(thread)d |
线程ID | 140736123456 | ⭐⭐⭐ |
%(threadName)s |
线程名称 | Thread-1 | ⭐⭐⭐ |
%(created)f |
创建时间戳(浮点数) | 1690454445.123456 | ⭐⭐ |
%(msecs)d |
毫秒部分 | 456 | ⭐⭐ |
%(relativeCreated)d |
相对创建时间(毫秒) | 1234 | ⭐⭐ |
%(process)d |
进程ID | 12345 | ⭐⭐⭐ |
%(exc_info)s |
异常信息(如果有) | Traceback... | ⭐⭐⭐⭐ |
%(exc_text)s |
异常文本 | 同上 | ⭐⭐⭐ |
%(stack_info)s |
堆栈信息 | Stack trace... | ⭐⭐⭐ |
9. 异常处理
异常就是程序在运行的时候产生的错误
比如:
python
print(1/0)
# 输出结果:
# print(1/0)
# ~^~
# ZeroDivisionError: division by zero
直接显示这个错误,并不是特别的友好,所有python提供try..except语句来处理异常
语法如下:
python
try:
# 尝试执行一些代码
except 错误类型 as 变量:
# 出现该错误类型的时候, 执行这一段代码
finally:
# 不论出错还是不出错, 都会执行这一段代码
这里面的finally是可以省略的.
说一下具体的执行流程:
- 先执行try中的代码, 如果出现了错误. 就自动执行except中的代码. 最后执行finally中的语句
- 如果try中没有错误. 就直接执行finally中的代码
python
try:
# 可能抛出异常的代码
result = 10 / 0
print(f"结果是: {result}")
except ZeroDivisionError:
# 处理特定异常
print("除数不能为零")
finally:
# 无论是否发生异常都会执行
print("程序执行完毕,清理工作完成")
except可以出现多次. 表示, 出现不同的错误时, 有不同的解决方案
python
try:
# 尝试执行除法
result = a / b
print(f"{a} / {b} = {result}")
return result
except ZeroDivisionError:
# 处理除零异常
print(f"错误:除数 {b} 不能为零")
return None
except TypeError:
# 处理类型错误
print("错误:请输入有效的数字")
return None
finally:
# 无论是否发生异常都会执行
print("除法操作已结束,记录日志...")
在出现问题的时候我们也是可以把问题给抛出去的,使用raise
python
try:
# 检查除数是否为零,主动抛出异常
if b == 0:
raise ValueError("除数不能为零") # 主动抛出异常
result = a / b
print(f"{a} / {b} = {result}")
return result
except ValueError as e:
# 捕获我们自己抛出的异常
print(f"捕获到自定义异常: {e}")
return None
finally:
print("除法操作结束")
最后,我们需要处理异常的时候使用try-catch,抛出异常的时候使用raise
10. traceback
Traceback 是 Python 在程序发生异常时打印的错误信息,它显示了从异常发生的位置到程序入口的调用堆栈,帮助我们定位和调试错误。
python
try:
print(1/0)
except:
print("出错了")
print(traceback.format_exc()) # 错误信息就能看到了
完整的一个流程:
python
import traceback
import logging
# 配置日志
logging.basicConfig(
filename='x1.txt',
format='%(asctime)s - %(name)s - %(levelname)s - %(module)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
level=logging.DEBUG
)
try:
print(1 / 0) # 发生 ZeroDivisionError
except Exception as e: # 推荐指定异常类型
# 方法1:使用 traceback.format_exc()
logging.error(f"发生异常: {e}\n{traceback.format_exc()}")
# 方法2:更简洁的方式(推荐)
# logging.error("发生异常", exc_info=True) # 自动记录完整堆栈
11. zipfile模块
zipfile 是 Python 标准库,用于处理 ZIP 压缩文件,支持:
- 创建新的 ZIP 文件
- 读取现有 ZIP 文件
- 添加、删除、提取文件
- 支持压缩和解压缩
python
import zipfile
import os
# ============ 创建 ZIP 压缩文件 ============
# 使用 with 语句自动管理资源(推荐)
with zipfile.ZipFile("zip_dir/abc.zip", mode="w") as f:
f.write("x1.txt")
f.write("x2.txt")
print("压缩文件创建成功")
# ============ 全部解压 ============
# 使用 with 语句
with zipfile.ZipFile("zip_dir/abc.zip", mode="r") as f:
f.extractall("zip_dir/abc") # 全部解压缩到文件夹
print("全部解压完成")
# ============ 逐个解压 ============
with zipfile.ZipFile("zip_dir/abc.zip", mode="r") as f:
for name in f.namelist():
f.extract(name, "zip_dir/abc")
print(f"已解压: {name}")
12. 正则表达式
是一种强大的文本处理工具,它使用一种特殊的字符串来描述、匹配一系列符合某个句法规则的字符串。因为正则的内容非常的多。所以这里介绍一些常用的元字符正则表达。
12.1 基本元字符
. (点号)
-
匹配除换行符(
\n)外的任意单字符 -
示例:a.b匹配"abb","a b","aab"等等这些
^(脱字符)
- 匹配字符串的开始位置
- 示例:
^abc匹配以"abc"开头的字符串
$(美元符)
- 匹配字符串的结束位置
- 示例:
xyz$匹配以"xyz"结尾的字符串
\(反斜杠)
- 转义字符,使后面的字符失去特殊的意义
.\匹配实际的点号而不是任意字符
12.2 字符类元字符
[](方括号)
- 定义字符集合,匹配其中的任意一个字符
- 示例:aeiou匹配任意一个元音字母
[^](否定字符类)
-
匹配不在括号中的任意字符
-
示例:
[^0-9]匹配任意非数字字符
-(连字符)
- 在字符类中表示范围
- 示例
[a-z]匹配任意小写字母
12.3 量词元字符
*(星号)
- 匹配前面的子表达式零次或者多次
- 示例:ab*c匹配"ac","abc","abbc"等
+(加号)
- 匹配前面的子表达式一次或者多次
- 示例:
ab+c匹配"abc","abbc"等
?(问号)
- 匹配前面的子表达式零次或者一次
- 示例:
ab?c匹配"ac","abc"
{n}(花括号)
- 精确匹配n次
- 示例:
a{2}匹配"aa"
{n,}
- 至少匹配n次
- 示例:a{2,}匹配"aa","aaa"等
{n,m}
- 匹配n到m次
- 示例
a{2,3}匹配"aa","aaa"
12.4 分组和选择元字符
()(圆括号)
- 定义子表达式或者捕获组
- 示例:(ab)+匹配"ab","abab"等
|(竖线)
- 表示"或"关系
- 示例:
a|b匹配"a"或者"b"
12.5 特殊字符类元字符
\d
- 匹配任意数字,等价于0-9
\D
- 匹配任意非数字,等价于
[^0-9]
\w
- 匹配任意单词字符(字母、数字、下划线),等价于
[a-zA-Z0-9_]
\W
- 匹配任意非单词字符,等价于
[^a-zA-Z0-9_]
\s
- 匹配任意空白字符(空格,制表符,换行符等等)
\S
- 匹配任意非空白字符
12.6 边界匹配元字符
\b
- 匹配单词边界
- 示例:
\bshe\b匹配"she"但不匹配"sheet"
\B
- 匹配非单词边界
- 示例:
\Bcat\B匹配"scattered"中的"cat"不匹配单独的"cat"
12.7 其他元字符
\n
- 匹配换行符
\t
- 匹配制表符
\r
- 匹配回车符
\f
- 匹配换页符
\v
- 匹配垂直制表符
12.8 贪婪与非贪婪量词
默认情况下,量词(*,+,?,{})是贪婪的,会尽可能的匹配更多的字符。在量词后面加?可以使其变得非贪婪(懒惰)模式:
*?:零次或者多次,但是尽可能的少+?:一次或者多次,但是尽可能的少??:零次或者一次,但是尽可能的少{n,m}?:n到m次,但是尽可能的少
示例:a{2,4}?b。优先匹配最少次数 n。 文本 "aaab": a{2,4}? 先尝试匹配 2 个 a,得到 aa,后面是 a ≠ b,失败。 扩展为匹配 3 个 a,得到 aaa,后面是 b 成功。 结果匹配到 "aaab"。
12.9 正向和负向预查
(?=...) (正向肯定预查)
-
匹配后面跟着特定模式的位置
-
示例:
iPhone(?=1[45])匹配后面跟着14或15的"iPhone"
(?!...) (正向否定预查)
-
匹配后面不跟着特定模式的位置
-
示例:iPhone(?!145) 匹配后面不跟着14或15的"iPhone"
(?<=...) (反向肯定预查)
-
匹配前面是特定模式的位置
-
示例:(?<=Samsung|Google)A-Z\w+ 匹配前面是Samsung或Google的单词
(?<!...) (反向否定预查)
-
匹配前面不是特定模式的位置
-
示例:(?<!Samsung|Google)A-Z\w+ 匹配前面不是Samsung或Google的单词
13. re 模块
re模块是python提供的一套关于处理正则表达式的模块。
- findall 查找所有 返回列表
python
lst = re.findall("a", "apple approve abandon")
print(f"lst = {lst} lst_type = {type(lst)}")
# 输出结果:lst = ['a', 'a', 'a', 'a'] lst_type = <class 'list'>
- search 会进行匹配,但是如果匹配到第一个结果,就会返回这个结果,如果匹配不上就会返回None
python
# search 会进行匹配,但是如果匹配到第一个结果,就会返回这个结果,如果匹配不上就会返回None
res = re,search(r"\d", "这个是一个5位小数").group()
print(res)
# 输出结果:5
- match 只能从字符串的开头进行匹配
python
# match 只能从字符串的开头进行匹配
res = re.match('m', 'more').group()
print(res)
# 输出结果:m
- finditer 和 findall 差不多只不过是返回的迭代器
python
# finditer 和 findall 差不多只不过是返回的迭代器
itr = re.finditer("a", "apple approve abandon")
for i in itr:
print(i.group())
# 输出结果:
# a
# a
# a
# a
- re其他操作
python
text = "我的电话号码是 138-1234-5678"
# 基本替换
new_text = re.sub(r'\d', 'X', text)
print(new_text)
# 输出: 我的电话号码是 XXX-XXXX-XXXX
=======================================
text = "这里有 10 个苹果, 20 个橘子, 30 个香蕉"
# 替换并返回替换次数
new_text, count = re.subn(r'\d+', 'N', text)
print(f"替换后: {new_text}")
print(f"替换次数: {count}")
# 输出:
# 替换后: 这里有 N 个苹果, N 个橘子, N 个香蕉
# 替换次数: 3
=======================================
text = "苹果,香蕉;橘子 葡萄|西瓜"
# 按多个分隔符分割
result = re.split(r'[,;\s|]+', text)
print(result)
# 输出: ['苹果', '香蕉', '橘子', '葡萄', '西瓜']
=======================================
# 编译正则表达式(提高性能,特别是重复使用时)
pattern = re.compile(r'\d{3}-\d{4}-\d{4}')
# 使用编译后的模式
text1 = "电话: 138-1234-5678"
text2 = "备用: 139-2345-6789"
print(pattern.search(text1).group()) # 138-1234-5678
print(pattern.search(text2).group()) # 139-2345-6789
14. os 模块
os 模块全称 Operating System ,它提供了与操作系统进行交互的接口。简单说,它可以让你用 Python 代码来操作文件和文件夹、获取系统信息、执行系统命令等。
python
所有和操作系统相关的内容都在os模块
os.makedirs('dirname1/dirname2') 可生成多层递归目录
os.removedirs('dirname1') 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
os.mkdir('dirname') 生成单级目录;相当于shell中mkdir dirname
os.rmdir('dirname') 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
os.listdir('dirname') 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
os.remove() 删除一个文件
os.rename("oldname","newname") 重命名文件/目录
os.system("bash command") 运行shell命令,直接显示
os.popen("bash command").read() 运行shell命令,获取执行结果
os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径
os.chdir("dirname") 改变当前脚本工作目录;相当于shell下cd
# os.path
os.path.abspath(path) 返回path规范化的绝对路径
os.path.split(path) 将path分割成目录和文件名二元组返回
os.path.dirname(path) 返回path的目录。其实就是os.path.split(path)的第一个元素
os.path.basename(path) 返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素
os.path.exists(path) 如果path存在,返回True;如果path不存在,返回False
os.path.isabs(path) 如果path是绝对路径,返回True
os.path.isfile(path) 如果path是一个存在的文件,返回True。否则返回False
os.path.isdir(path) 如果path是一个存在的目录,则返回True。否则返回False
os.path.join(path1[, path2[, ...]]) 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
os.path.getatime(path) 返回path所指向的文件或者目录的最后访问时间
os.path.getmtime(path) 返回path所指向的文件或者目录的最后修改时间
os.path.getsize(path) 返回path的大小
# 特殊属性:
os.sep 输出操作系统特定的路径分隔符,win下为"\\",Linux下为"/"
os.linesep 输出当前平台使用的行终止符,win下为"\r\n",Linux下为"\n"
os.pathsep 输出用于分割文件路径的字符串 win下为;,Linux下为:
os.name 输出字符串指示当前使用平台。win->'nt'; Linux->'posix'
- 使用os.walk遍历文件夹
python
import os
for root, dirs, fils in os.walk("."):
for dir in dirs:
print(os.path.join(root, dir))
for f in fils:
print(os.path.join(root, f))
- 递归遍历文件夹
python
def func(path):
lst = os.listdir(path)
for f_name in lst:
new_path = os.path.join(path, f_name)
if os.path.isdir(new_path):
func(new_path)
else:
print(new_path)
func("./")
15. sys 模块
| 属性/方法 | 说明 |
|---|---|
sys.argv |
命令行参数列表,第一个元素是程序本身路径 |
sys.exit([arg]) |
退出程序,可选参数为退出码或错误信息 |
sys.path |
模块搜索路径列表,可动态添加自定义路径 |
sys.stdin |
标准输入流,用于读取键盘输入或管道数据 |
sys.stdout |
标准输出流,print() 默认输出到这里 |
sys.stderr |
标准错误流,用于输出错误信息 |
sys.version |
Python 版本字符串,如 "3.9.7 ..." |
sys.version_info |
Python 版本元组,如 (3, 9, 7) |
sys.platform |
操作系统标识:'win32' / 'linux' / 'darwin' |
sys.getrecursionlimit() |
获取递归深度限制,默认 1000 |
sys.setrecursionlimit(n) |
设置递归深度限制 |
sys.getsizeof(obj) |
获取对象占用的内存大小(字节) |
sys.modules |
已导入模块的字典缓存 |
16. 模块和包
16.1 模块
- 模块就是一个 .py 文件,里面包含函数、类、变量等代码。
python
# 创建一个模块: my_math.py
def add(a, b):
return a + b
def multiply(a, b):
return a * b
PI = 3.14159
导入模块示例如下:
python
# 方式1: 导入整个模块
import my_math
print(my_math.add(3, 5)) # 8
print(my_math.PI) # 3.14159
# 方式2: 导入模块并起别名
import my_math as mm
print(mm.multiply(3, 5)) # 15
# 方式3: 只导入部分内容
from my_math import add, PI
print(add(3, 5)) # 8
# print(multiply(3, 5)) # 报错,未导入
# 方式4: 导入所有内容(不推荐,容易命名冲突)
from my_math import *
print(add(3, 5)) # 8
导入模块的时候都做了些什么?
首先. 在导入模块的一瞬间. python解释器会先通过sys.modules来判断该模块是否已经导入了该模块. 如果已经导入了则不再导入. 如果该模块还未导入过. 则系统会做三件事.
- 为导入的模块创立新的名称空间(独立的内存)
- 在新创建的名称空间中运行该模块中的代码
- 创建模块的名字. 并使用该名称作为该模块在当前模块中引用的名字.
特别特别要注意. 如果我们在不同的模块中引入了同一个模块. 并且在某一个模块中改变了被引入模块中的全局变量. 则其他模块看到的值也跟着变. 原因是python的模块只会引入一次. 大家共享同一个名称空间
正确的导入模块的顺序:
- 所有的模块导入都要写在最上面. 这是最基本的
- 先引入内置模块
- 再引入扩展模块
- 最后引入你自己定义的模块
16.2 包
- 包是一个包含 init.py 文件的文件夹,用于组织多个模块。
python
my_package/ # 包名
__init__.py # 标识这是一个包(可以为空)
math_utils.py # 模块
string_utils.py # 模块
network/
__init__.py # 子包
http_client.py # 子模块
导入保重的模块的示例:
python
# 方式1: 导入整个模块
import my_package.math_utils
result = my_package.math_utils.add(3, 5)
# 方式2: 简化路径
from my_package import math_utils
result = math_utils.add(3, 5)
# 方式3: 直接导入函数
from my_package.math_utils import add, multiply
result = add(3, 5)
# 方式4: 导入子包中的模块
from my_package.network.http_client import get_data
data = get_data('https://api.example.com')
16.3 __init__的作用
- 让 Python 知道这个文件夹是一个包。
- 可以在 init .py 中定义 all 控制 from package import * 的内容:
python
# my_package/__init__.py
__all__ = ['math_utils', 'string_utils'] # 只导入这两个
- 在 init.py 中预先导入常用内容:
python
# my_package/__init__.py
from .math_utils import add, multiply
from .string_utils import to_upper
# 现在可以直接这样用:
from my_package import add, to_upper
16.4 相对导入与绝对导入
包结构示例:
python
project/
__init__.py
main.py
utils/
__init__.py
helper.py
validator.py
crawler/
__init__.py
spider.py
parser.py
- 绝对导入
python
# crawler/spider.py
from project.utils.helper import clean_data
from project.crawler.parser import parse_html
- 绝对导入
python
# crawler/spider.py
from ..utils.helper import clean_data # .. 表示上级目录
from .parser import parse_html # . 表示当前目录
注意 :相对导入只能在包内部使用,不能直接在顶层脚本(如 main.py)中使用。
我们自己创建的py文件的名字不要和系统内置的模块重名
17. 第三方模块安装和使用
css
pip install 模块 -i 国内源
注意, 如果pip在控制台输入没有反应, 很可能是环境变量没有配置成功. 需要把python中的Script文件夹也配置到path环境变量中才可以.
有些情况我们安装某些模块的时候可能需要对pip进行升级
python
pip install -U pip # 更新pip
pip uninstall 模块 # 卸载模块
pip show 模块 # 显示xxx模块
pip list # 显示出已安装的模块