欢迎回来!🎉 这节课我们要学习如何组织代码——模块(Module)和包(Package),让我们的项目更有条理!
前五节课我们学会了: - 变量和基本数据类型 - 条件判断和循环 - 列表和字典 - 函数(代码的魔法师) - 文件操作(数据持久化)
这节课我们要学习如何把代码组织得更好,以及如何使用别人写好的库!
模块就是一个 .py 文件,里面包含了相关的函数、类和变量。
✅ 代码复用:同一个文件可以在多个项目中使用
✅ 组织代码:把相关功能放在一起
✅ 避免命名冲突:不同模块可以有同名函数
✅ 便于维护:修改一个模块不影响其他代码
# 导入整个模块
import math
print(math.pi) # 圆周率
print(math.sqrt(16)) # 平方根
print(math.sin(math.pi/2)) # 正弦函数
# 只导入需要的函数或变量
from math import pi, sqrt
print(pi)
print(sqrt(25))
# 给模块起别名
import math as m
print(m.pi)
print(m.sqrt(9))
# 给函数起别名
from math import sqrt as square_root
print(square_root(16))
# 导入模块中的所有内容(可能导致命名冲突)
from math import *
print(pi)
print(sqrt(4))
让我们创建一个实用的工具模块!
my_tools.py# my_tools.py - 我的工具模块
def greet(name):
"""问候函数"""
return f"你好,{name}!"
def add(a, b):
"""加法函数"""
return a + b
def multiply(a, b):
"""乘法函数"""
return a * b
def calculate_area(radius):
"""计算圆的面积"""
import math
return math.pi * radius ** 2
# 模块级别的变量
AUTHOR = "Python学习者"
VERSION = "1.0"
# main.py - 主程序
import my_tools
# 使用模块中的函数
print(my_tools.greet("小明"))
print(f"3 + 5 = {my_tools.add(3, 5)}")
print(f"4 * 6 = {my_tools.multiply(4, 6)}")
print(f"半径为5的圆面积:{my_tools.calculate_area(5):.2f}")
# 使用模块中的变量
print(f"\n作者:{my_tools.AUTHOR}")
print(f"版本:{my_tools.VERSION}")
__name__ 和 __main__# my_tools.py(改进版)
def greet(name):
return f"你好,{name}!"
def add(a, b):
return a + b
# 测试代码
if __name__ == "__main__":
# 只有直接运行这个文件时才会执行
print("这是my_tools模块的测试代码")
print(greet("测试"))
print(f"1 + 2 = {add(1, 2)}")
原理说明:
- 当直接运行文件时,__name__ 的值是 "__main__"
- 当被导入时,__name__ 的值是模块名("my_tools")
包就是一个文件夹,里面包含多个模块和一个特殊的 __init__.py 文件。
my_package/
├── __init__.py # 必须有!标识这是一个包
├── module1.py # 模块1
├── module2.py # 模块2
└── subpackage/ # 子包
├── __init__.py
└── module3.py
# 创建目录结构
# my_math/
# __init__.py
# basic.py
# advanced.py
# basic.py
def add(a, b):
return a + b
def subtract(a, b):
return a - b
def multiply(a, b):
return a * b
def divide(a, b):
if b == 0:
raise ValueError("除数不能为零")
return a / b
# advanced.py
import math
def square_root(x):
return math.sqrt(x)
def power(base, exponent):
return math.pow(base, exponent)
def factorial(n):
if n < 0:
raise ValueError("负数没有阶乘")
result = 1
for i in range(1, n + 1):
result *= i
return result
# __init__.py
from .basic import add, subtract, multiply, divide
from .advanced import square_root, power, factorial
__all__ = ['add', 'subtract', 'multiply', 'divide',
'square_root', 'power', 'factorial']
# 方式1:导入整个包
import my_math
print(my_math.add(3, 5))
print(my_math.factorial(5))
# 方式2:从包中导入特定内容
from my_math import add, factorial
print(add(10, 20))
print(factorial(10))
# 方式3:导入子模块
from my_math import basic
print(basic.multiply(4, 5))
Python自带了很多强大的标准库!
import sys
print("Python版本:", sys.version)
print("操作系统平台:", sys.platform)
print("命令行参数:", sys.argv)
print("模块搜索路径:", sys.path)
# 退出程序
# sys.exit(0)
import os
print("当前工作目录:", os.getcwd())
print("环境变量:", os.environ.get("PATH"))
# 列出目录内容
print("目录内容:", os.listdir("."))
# 路径操作
print("路径拼接:", os.path.join("folder", "file.txt"))
print("是否存在:", os.path.exists("test.txt"))
print("是否是文件:", os.path.isfile("test.txt"))
print("是否是目录:", os.path.isdir("."))
from datetime import datetime, date, timedelta
# 当前时间
now = datetime.now()
print("当前时间:", now)
print("年:", now.year)
print("月:", now.month)
print("日:", now.day)
print("时:", now.hour)
print("分:", now.minute)
print("秒:", now.second)
# 格式化输出
print("格式化:", now.strftime("%Y-%m-%d %H:%M:%S"))
# 日期计算
today = date.today()
tomorrow = today + timedelta(days=1)
yesterday = today - timedelta(days=1)
print("今天:", today)
print("明天:", tomorrow)
print("昨天:", yesterday)
# 字符串转日期
date_str = "2024-01-15"
date_obj = datetime.strptime(date_str, "%Y-%m-%d")
print("字符串转日期:", date_obj)
import random
# 随机整数
print("随机整数(0-9):", random.randint(0, 9))
# 随机浮点数
print("随机浮点数(0-1):", random.random())
print("随机浮点数(1-10):", random.uniform(1, 10))
# 随机选择
fruits = ["苹果", "香蕉", "橙子", "葡萄"]
print("随机选择:", random.choice(fruits))
# 随机打乱
random.shuffle(fruits)
print("打乱后:", fruits)
# 随机抽样
print("随机抽取2个:", random.sample(fruits, 2))
import json
# Python对象转JSON
data = {
"name": "小明",
"age": 18,
"hobbies": ["读书", "游泳"]
}
json_str = json.dumps(data, ensure_ascii=False, indent=2)
print("JSON字符串:", json_str)
# JSON转Python对象
python_obj = json.loads(json_str)
print("Python对象:", python_obj)
# 读写JSON文件
with open("data.json", "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
with open("data.json", "r", encoding="utf-8") as f:
loaded_data = json.load(f)
print("从文件读取:", loaded_data)
import re
# 查找匹配
text = "我的电话是13812345678,邮箱是test@example.com"
# 查找手机号
phone_pattern = r"1[3-9]\d{9}"
phones = re.findall(phone_pattern, text)
print("手机号:", phones)
# 查找邮箱
email_pattern = r"\w+@\w+\.\w+"
emails = re.findall(email_pattern, text)
print("邮箱:", emails)
# 替换
new_text = re.sub(phone_pattern, "***", text)
print("替换后:", new_text)
# 验证
def is_valid_phone(phone):
pattern = r"^1[3-9]\d{9}$"
return re.match(pattern, phone) is not None
print("13812345678有效吗?", is_valid_phone("13812345678"))
print("123456789有效吗?", is_valid_phone("123456789"))
# 安装包
pip install requests
# 安装特定版本
pip install requests==2.28.0
# 升级包
pip install --upgrade requests
# 卸载包
pip uninstall requests
# 查看已安装的包
pip list
# 查看包信息
pip show requests
import requests
# GET请求
response = requests.get("https://api.github.com")
print("状态码:", response.status_code)
print("响应内容:", response.json())
# POST请求
data = {"key": "value"}
response = requests.post("https://httpbin.org/post", json=data)
print(response.json())
import pandas as pd
# 创建DataFrame
data = {
"姓名": ["小明", "小红", "小刚"],
"年龄": [18, 17, 19],
"成绩": [90, 85, 95]
}
df = pd.DataFrame(data)
print(df)
# 读取CSV
# df = pd.read_csv("data.csv")
# 基本统计
print("\n统计信息:")
print(df.describe())
# 筛选
print("\n成绩大于90的:")
print(df[df["成绩"] > 90])
让我们创建一个完整的工具包!
# 创建目录结构
# utils/
# __init__.py
# string_utils.py
# math_utils.py
# file_utils.py
# date_utils.py
# string_utils.py
def reverse_string(s):
"""反转字符串"""
return s[::-1]
def count_words(s):
"""统计单词数"""
return len(s.split())
def is_palindrome(s):
"""判断是否是回文"""
s = s.lower().replace(" ", "")
return s == s[::-1]
def capitalize_sentences(s):
"""首字母大写"""
sentences = s.split('. ')
return '. '.join(sentence.capitalize() for sentence in sentences)
# math_utils.py
def is_prime(n):
"""判断是否是质数"""
if n <= 1:
return False
for i in range(2, int(n ** 0.5) + 1):
if n % i == 0:
return False
return True
def fibonacci(n):
"""生成斐波那契数列"""
fib = []
a, b = 0, 1
for _ in range(n):
fib.append(b)
a, b = b, a + b
return fib
def gcd(a, b):
"""最大公约数"""
while b:
a, b = b, a % b
return a
def lcm(a, b):
"""最小公倍数"""
return a * b // gcd(a, b)
# file_utils.py
import os
def get_file_extension(filename):
"""获取文件扩展名"""
return os.path.splitext(filename)[1]
def read_file_lines(filename):
"""读取文件所有行"""
with open(filename, 'r', encoding='utf-8') as f:
return f.readlines()
def count_file_lines(filename):
"""统计文件行数"""
with open(filename, 'r', encoding='utf-8') as f:
return sum(1 for _ in f)
def find_files_by_extension(directory, extension):
"""查找指定扩展名的文件"""
found = []
for root, dirs, files in os.walk(directory):
for file in files:
if file.endswith(extension):
found.append(os.path.join(root, file))
return found
# date_utils.py
from datetime import datetime, date
def get_age(birthdate):
"""计算年龄"""
today = date.today()
return today.year - birthdate.year - ((today.month, today.day) < (birthdate.month, birthdate.day))
def is_leap_year(year):
"""判断是否是闰年"""
return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)
def days_until(target_date):
"""计算到目标日期的天数"""
today = date.today()
delta = target_date - today
return delta.days
def format_date(date_obj, format="%Y-%m-%d"):
"""格式化日期"""
return date_obj.strftime(format)
# __init__.py
from .string_utils import reverse_string, count_words, is_palindrome, capitalize_sentences
from .math_utils import is_prime, fibonacci, gcd, lcm
from .file_utils import get_file_extension, read_file_lines, count_file_lines, find_files_by_extension
from .date_utils import get_age, is_leap_year, days_until, format_date
__version__ = "1.0.0"
__author__ = "Python学习者"
# 使用这个工具包
import utils
# 测试字符串工具
print("反转字符串:", utils.reverse_string("Hello"))
print("是回文吗?", utils.is_palindrome("A man a plan a canal Panama"))
# 测试数学工具
print("是质数吗?", utils.is_prime(17))
print("斐波那契数列:", utils.fibonacci(10))
# 测试日期工具
from datetime import date
birthdate = date(2000, 5, 15)
print("年龄:", utils.get_age(birthdate))
print("2024是闰年吗?", utils.is_leap_year(2024))
今天我们学会了:
✅ 模块:单个.py文件,包含函数和变量
✅ 导入模块:import、from...import、as
✅ 创建模块:自己写.py文件
✅ 包:包含多个模块的文件夹
✅ 标准库:sys、os、datetime、random、json、re
✅ 第三方库:使用pip安装,requests、pandas等
✅ name:判断是直接运行还是被导入
下节课预告:我们会学习面向对象编程(OOP),这是Python编程的重要范式!
继续加油!你已经掌握了Python编程的核心技能!💪