Python So Easy 大虫小呓三部曲 - 进阶篇

你好,我是大虫,哈哈,我们又见面啦!

由于之前写的一篇《【全网最全】50个Python处理Excel示例代码,覆盖95%日常使用场景》 大家反馈不错,于是就筹划了本系列教程。

如果你已经完成了【入门篇】的学习,那么恭喜你已经踏入了编程的世界!

在【进阶篇】中,我们将深入探讨Python的一些核心概念,比如面向对象编程、装饰器、生成器等。

这些内容会让你更深入地理解Python的设计哲学,也会让你的代码更加优雅和高效。

学习过程中可能会遇到一些挑战,但请记住:每个优秀的程序员都是从不断解决问题中成长起来的。

让我们一起继续这段精彩的Python学习之旅吧!记住,编程没有捷径,但有乐趣!

目录

  1. 面向对象编程
  2. 模块与包
  3. 常用标准库
  4. 列表推导式与生成器
  5. 装饰器
  6. 上下文管理器
  7. 正则表达式
  8. 多线程与多进程
  9. 虚拟环境与包管理
  10. 单元测试
  11. 实战项目:个人博客系统CLI版本

1. 面向对象编程

面向对象编程(OOP)是一种编程范式,通过将数据和操作数据的方法封装在对象中,让程序更易于理解和维护。就像现实世界中的对象一样,每个对象都有自己的属性和行为,这样代码就更贴近我们的思维方式了。

面向对象编程(OOP)是Python的重要特性,它能帮助我们更好地组织和管理代码。

类和对象

面向对象编程(OOP)是Python的重要特性。

python 复制代码
# 定义一个类
class Dog:
    # 类变量(所有实例共享)
    species = "犬类"
    
    # 构造方法,初始化对象
    def __init__(self, name, age):
        # 实例变量(每个实例独有)
        self.name = name
        self.age = age
    
    # 实例方法
    def bark(self):
        return f"{self.name}在汪汪叫!"
    
    # 另一个实例方法
    def get_info(self):
        return f"我是{self.name},今年{self.age}岁,属于{self.species}"

# 创建对象(实例化)
dog1 = Dog("小白", 3)
dog2 = Dog("小黑", 5)

# 调用对象的方法
print(dog1.bark())
print(dog2.get_info())

# 访问对象的属性
print(f"{dog1.name}是{dog1.species}")

# 继承
class Puppy(Dog):
    def __init__(self, name, age, toy):
        # 调用父类的构造方法
        super().__init__(name, age)
        self.toy = toy
    
    # 重写父类的方法
    def bark(self):
        return f"{self.name}在轻轻叫,还不会大声汪汪!"
    
    # 子类特有的方法
    def play(self):
        return f"{self.name}在玩{self.toy}"

# 创建子类对象
puppy = Puppy("小花", 1, "球")
print(puppy.bark())
print(puppy.play())
print(puppy.get_info())  # 调用继承自父类的方法

# 封装示例
class BankAccount:
    def __init__(self, owner, balance=0):
        self.owner = owner
        # 使用双下划线表示私有属性(名称改写)
        self.__balance = balance
    
    # 提供公共方法来访问私有属性
    def deposit(self, amount):
        if amount > 0:
            self.__balance += amount
            return f"存款{amount}元成功"
        return "存款金额必须大于0"
    
    def withdraw(self, amount):
        if 0 < amount <= self.__balance:
            self.__balance -= amount
            return f"取款{amount}元成功"
        return "余额不足或金额无效"
    
    def get_balance(self):
        return f"账户余额: {self.__balance}元"

# 使用银行账户类
account = BankAccount("大虫", 1000)
print(account.deposit(500))
print(account.withdraw(200))
print(account.get_balance())
# print(account.__balance)  # 这会报错,因为是私有属性

2. 模块与包

模块是包含Python代码的文件,包是组织模块的目录结构。使用模块和包可以让我们更好地组织代码,实现代码的重用。这就像图书馆的分类系统,帮你快速找到需要的书籍(代码)。

模块是一个包含Python代码的文件,包是包含多个模块的目录。

python 复制代码
# 导入标准库模块
import math
print(math.sqrt(16))  # 4.0

# 导入模块中的特定函数
from math import pi, cos
print(f"圆周率: {pi}")
print(f"cos(0): {cos(0)}")

# 导入模块并给它起别名
import datetime as dt
now = dt.datetime.now()
print(f"当前时间: {now}")

# 创建自己的模块
# 假设我们创建了一个名为 my_utils.py 的文件,内容如下:
"""
def greet(name):
    return f"你好, {name}!"

def calculate_area(radius):
    import math
    return math.pi * radius ** 2
"""

# 然后在其他文件中导入:
# import my_utils
# print(my_utils.greet("大虫"))
# print(my_utils.calculate_area(5))

# 包是包含__init__.py文件的目录
# 目录结构示例:
# mypackage/
#     __init__.py
#     module1.py
#     module2.py
# 
# 使用方式:
# from mypackage import module1
# from mypackage.module1 import some_function

3. 常用标准库

Python标准库提供了丰富的功能模块。

python 复制代码
# 日期和时间处理
import datetime
import time

# 获取当前时间
now = datetime.datetime.now()
print(f"当前时间: {now}")

# 创建特定日期
birthday = datetime.datetime(2000, 1, 1)
print(f"生日: {birthday}")

# 时间计算
today = datetime.date.today()
future_date = today + datetime.timedelta(days=100)
print(f"100天后是: {future_date}")

# 暂停执行
print("开始等待...")
time.sleep(2)  # 暂停2秒
print("等待结束!")

# 随机数生成
import random

# 生成随机整数
print(random.randint(1, 10))  # 1到10之间的随机整数

# 从列表中随机选择
colors = ["红", "黄", "蓝", "绿"]
print(random.choice(colors))

# 打乱列表顺序
numbers = [1, 2, 3, 4, 5]
random.shuffle(numbers)
print(numbers)

# 文件和路径操作
import os
import pathlib

# 获取当前工作目录
print(f"当前目录: {os.getcwd()}")

# 列出目录内容
print(f"目录内容: {os.listdir('.')}")

# 使用pathlib(更现代的方式)
current_path = pathlib.Path('.')
print(f"当前路径: {current_path}")
print(f"目录中的文件: {[f.name for f in current_path.iterdir() if f.is_file()]}")

# JSON处理
import json

# Python对象转JSON
data = {
    "name": "大虫",
    "age": 25,
    "skills": ["Python", "Java", "C++"]
}
json_str = json.dumps(data, ensure_ascii=False, indent=2)
print(json_str)

# JSON转Python对象
json_data = '{"name": "小虫", "age": 30}'
person = json.loads(json_data)
print(person)

4. 列表推导式与生成器

列表推导式提供了一种简洁的创建列表的方式。

python 复制代码
# 传统方式创建列表
squares = []
for x in range(10):
    squares.append(x**2)
print(squares)

# 使用列表推导式
squares = [x**2 for x in range(10)]
print(squares)

# 带条件的列表推导式
even_squares = [x**2 for x in range(10) if x % 2 == 0]
print(even_squares)

# 处理字符串列表
words = ["hello", "world", "python", "programming"]
upper_words = [word.upper() for word in words]
print(upper_words)

lengths = [len(word) for word in words]
print(lengths)

# 嵌套列表推导式
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened = [num for row in matrix for num in row]
print(flattened)

# 字典推导式
square_dict = {x: x**2 for x in range(5)}
print(square_dict)

# 集合推导式
unique_lengths = {len(word) for word in words}
print(unique_lengths)

# 生成器表达式(节省内存)
# 与列表推导式的区别是使用圆括号而不是方括号
gen = (x**2 for x in range(10))
print(gen)  # <generator object <genexpr> at ...>
print(list(gen))  # 转换为列表查看内容

# 生成器函数
def fibonacci(n):
    a, b = 0, 1
    for _ in range(n):
        yield a
        a, b = b, a + b

# 使用生成器
fib = fibonacci(10)
print(list(fib))

# 生成器的优点是节省内存,只在需要时计算值

5. 装饰器

装饰器是修改或扩展函数行为的强大工具。

python 复制代码
# 简单装饰器示例
def my_decorator(func):
    def wrapper():
        print("函数执行前的操作")
        func()
        print("函数执行后的操作")
    return wrapper

@my_decorator
def say_hello():
    print("Hello!")

say_hello()

# 带参数的装饰器
def repeat(times):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(times):
                result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator

@repeat(3)
def greet(name):
    print(f"你好, {name}!")

greet("大虫")

# 计算函数执行时间的装饰器
import time

def timer(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"{func.__name__} 执行时间: {end_time - start_time:.4f}秒")
        return result
    return wrapper

@timer
def slow_function():
    time.sleep(1)
    return "完成"

print(slow_function())

# 使用functools.wraps保持原函数属性
from functools import wraps

def my_decorator(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        print(f"调用函数: {func.__name__}")
        return func(*args, **kwargs)
    return wrapper

@my_decorator
def example_function():
    """这是一个示例函数"""
    return "示例结果"

print(example_function.__name__)  # 如果没有@wraps,这里会显示wrapper
print(example_function.__doc__)   # 如果没有@wraps,这里会是None

6. 上下文管理器

上下文管理器用于确保资源得到正确管理(如文件的打开和关闭)。

python 复制代码
# 使用with语句(上下文管理器)
with open("example.txt", "w", encoding="utf-8") as file:
    file.write("使用上下文管理器写入文件")
# 文件会自动关闭,即使发生异常

# 自定义上下文管理器
class MyContextManager:
    def __enter__(self):
        print("进入上下文")
        return self
    
    def __exit__(self, exc_type, exc_value, traceback):
        print("退出上下文")
        if exc_type is not None:
            print(f"发生了异常: {exc_type.__name__}: {exc_value}")
        return False  # 返回False表示不抑制异常

# 使用自定义上下文管理器
with MyContextManager() as cm:
    print("在上下文内部")
    # raise ValueError("故意引发异常")  # 取消注释查看异常处理

# 使用contextlib模块创建上下文管理器
from contextlib import contextmanager

@contextmanager
def my_context():
    print("上下文开始")
    try:
        yield "上下文中的值"
    finally:
        print("上下文结束")

with my_context() as value:
    print(f"获取到值: {value}")

# 重定向标准输出的示例
from contextlib import redirect_stdout
import io

# 捕获print输出
f = io.StringIO()
with redirect_stdout(f):
    print("这段话不会显示在控制台")
    print("而是被捕获了")

output = f.getvalue()
print(f"捕获到的输出: {output}")

7. 正则表达式

正则表达式用于匹配字符串模式。

python 复制代码
import re

# 基本匹配
text = "我的电话号码是13812345678"
pattern = r'1[3-9]\d{9}'  # 匹配中国大陆手机号
match = re.search(pattern, text)
if match:
    print(f"找到手机号: {match.group()}")

# 查找所有匹配项
text = "Python是一种编程语言,python很受欢迎"
pattern = r'python'
matches = re.findall(pattern, text, re.IGNORECASE)  # 忽略大小写
print(f"找到{len(matches)}个匹配项: {matches}")

# 替换文本
text = "我的生日是2023-10-01"
pattern = r'(\d{4})-(\d{2})-(\d{2})'
replacement = r'\3/\2/\1'  # 改为日/月/年格式
new_text = re.sub(pattern, replacement, text)
print(new_text)

# 分割字符串
text = "apple,banana;orange:grape"
pattern = r'[,;:]'
parts = re.split(pattern, text)
print(parts)

# 编译正则表达式(提高性能)
pattern = re.compile(r'\b\w+@\w+\.\w+\b')  # 匹配邮箱
text = "联系我: zhang@example.com 或 li@test.org"
emails = pattern.findall(text)
print(emails)

# 常用正则表达式模式
# \d     匹配数字
# \w     匹配字母、数字、下划线
# \s     匹配空白字符
# .      匹配任意字符(除换行符)
# *      匹配前一个字符0次或多次
# +      匹配前一个字符1次或多次
# ?      匹配前一个字符0次或1次
# {n}    匹配前一个字符n次
# {n,m}  匹配前一个字符n到m次
# ^      匹配字符串开头
# $      匹配字符串结尾
# []     匹配方括号内的任意字符
# |      或运算

8. 多线程与多进程

多线程和多进程用于并发执行任务。

python 复制代码
# 多线程示例
import threading
import time

def worker(name, duration):
    print(f"线程 {name} 开始工作")
    time.sleep(duration)
    print(f"线程 {name} 工作完成")

# 创建线程
threads = []
for i in range(3):
    t = threading.Thread(target=worker, args=(f"Worker-{i}", 2))
    threads.append(t)
    t.start()

# 等待所有线程完成
for t in threads:
    t.join()

print("所有线程执行完毕")

# 线程锁(解决资源竞争问题)
import threading

counter = 0
lock = threading.Lock()

def increment():
    global counter
    for _ in range(100000):
        with lock:  # 使用锁保护共享资源
            counter += 1

# 创建多个线程修改共享变量
threads = []
for _ in range(5):
    t = threading.Thread(target=increment)
    threads.append(t)
    t.start()

for t in threads:
    t.join()

print(f"最终计数器值: {counter}")

# 多进程示例
from multiprocessing import Process, Pool
import os

def worker(name):
    print(f"进程 {name} (PID: {os.getpid()}) 开始工作")
    time.sleep(2)
    print(f"进程 {name} 工作完成")

# 创建进程
processes = []
for i in range(3):
    p = Process(target=worker, args=(f"Process-{i}",))
    processes.append(p)
    p.start()

# 等待所有进程完成
for p in processes:
    p.join()

print("所有进程执行完毕")

# 进程池
def square(x):
    return x * x

if __name__ == "__main__":
    with Pool(4) as pool:
        results = pool.map(square, [1, 2, 3, 4, 5])
    print(f"平方结果: {results}")

9. 虚拟环境与包管理

虚拟环境用于隔离项目依赖。

python 复制代码
# 创建虚拟环境 (Python 3.3+)
# python -m venv myenv

# 激活虚拟环境
# Windows: myenv\Scripts\activate
# macOS/Linux: source myenv/bin/activate

# 在虚拟环境中安装包
# pip install requests numpy pandas

# 查看已安装的包
# pip list

# 导出依赖列表
# pip freeze > requirements.txt

# 从依赖列表安装包
# pip install -r requirements.txt

# 退出虚拟环境
# deactivate

# 示例:使用requests库(需先安装)
# import requests
# 
# response = requests.get("https://api.github.com")
# if response.status_code == 200:
#     print("请求成功")
#     print(response.json())
# else:
#     print(f"请求失败,状态码: {response.status_code}")

10. 单元测试

单元测试用于验证代码的正确性。

python 复制代码
import unittest

# 被测试的函数
def add(a, b):
    return a + b

def is_even(number):
    return number % 2 == 0

# 测试类
class TestMathFunctions(unittest.TestCase):
    
    # 每个测试方法必须以test_开头
    def test_add_positive_numbers(self):
        self.assertEqual(add(2, 3), 5)
    
    def test_add_negative_numbers(self):
        self.assertEqual(add(-1, -1), -2)
    
    def test_add_mixed_numbers(self):
        self.assertEqual(add(-1, 1), 0)
    
    def test_is_even_true(self):
        self.assertTrue(is_even(4))
    
    def test_is_even_false(self):
        self.assertFalse(is_even(5))
    
    # 测试异常
    def test_add_with_strings(self):
        with self.assertRaises(TypeError):
            add("2", 3)

# 运行测试
if __name__ == "__main__":
    unittest.main()

# 使用setUp和tearDown
class TestStringMethods(unittest.TestCase):
    
    def setUp(self):
        # 在每个测试方法执行前运行
        self.test_string = "HelloWorld"
    
    def tearDown(self):
        # 在每个测试方法执行后运行
        pass
    
    def test_upper(self):
        self.assertEqual(self.test_string.upper(), "HELLOWORLD")
    
    def test_isupper(self):
        self.assertFalse(self.test_string.isupper())
        self.assertTrue("HELLO".isupper())

# 运行特定测试:
# python -m unittest test_module.TestClass
# python -m unittest test_module.TestClass.test_method

11. 实战项目:个人博客系统CLI版本

项目介绍

这个项目将综合运用面向对象编程、文件操作、异常处理等多个知识点,创建一个命令行界面的个人博客系统。通过这个项目,你可以体验到如何构建一个完整的应用程序。虽然界面简陋了点,但"麻雀虽小,五脏俱全",该有的功能一个不少!

个人博客系统(命令行版本), 综合运用面向对象、文件操作、异常处理等知识点。

python 复制代码
import json
import os
from datetime import datetime

class BlogPost:
    def __init__(self, title, content, author, date=None):
        self.title = title
        self.content = content
        self.author = author
        self.date = date or datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    
    def to_dict(self):
        return {
            "title": self.title,
            "content": self.content,
            "author": self.author,
            "date": self.date
        }
    
    @classmethod
    def from_dict(cls, data):
        return cls(data["title"], data["content"], data["author"], data["date"])

class BlogSystem:
    def __init__(self, filename="blog_posts.json"):
        self.filename = filename
        self.posts = self.load_posts()
    
    def load_posts(self):
        if os.path.exists(self.filename):
            try:
                with open(self.filename, "r", encoding="utf-8") as f:
                    data = json.load(f)
                    return [BlogPost.from_dict(post) for post in data]
            except (json.JSONDecodeError, KeyError):
                return []
        return []
    
    def save_posts(self):
        data = [post.to_dict() for post in self.posts]
        with open(self.filename, "w", encoding="utf-8") as f:
            json.dump(data, f, ensure_ascii=False, indent=2)
    
    def add_post(self, title, content, author):
        post = BlogPost(title, content, author)
        self.posts.append(post)
        self.save_posts()
        print("博客发布成功!")
    
    def list_posts(self):
        if not self.posts:
            print("暂无博客文章")
            return
        
        print("\n=== 博客文章列表 ===")
        for i, post in enumerate(self.posts, 1):
            print(f"{i}. {post.title}")
            print(f"   作者: {post.author}")
            print(f"   发布时间: {post.date}")
            print()
    
    def view_post(self, index):
        if 1 <= index <= len(self.posts):
            post = self.posts[index-1]
            print(f"\n标题: {post.title}")
            print(f"作者: {post.author}")
            print(f"发布时间: {post.date}")
            print(f"内容:\n{post.content}")
        else:
            print("无效的文章编号")
    
    def delete_post(self, index):
        if 1 <= index <= len(self.posts):
            deleted = self.posts.pop(index-1)
            self.save_posts()
            print(f"已删除文章: {deleted.title}")
        else:
            print("无效的文章编号")

def main():
    blog = BlogSystem()
    
    while True:
        print("\n=== 个人博客系统 ===")
        print("1. 发布新文章")
        print("2. 查看文章列表")
        print("3. 查看文章详情")
        print("4. 删除文章")
        print("5. 退出")
        
        choice = input("请选择操作 (1-5): ")
        
        try:
            if choice == "1":
                title = input("请输入文章标题: ")
                content = input("请输入文章内容: ")
                author = input("请输入作者姓名: ")
                blog.add_post(title, content, author)
            
            elif choice == "2":
                blog.list_posts()
            
            elif choice == "3":
                blog.list_posts()
                if blog.posts:
                    index = int(input("请输入要查看的文章编号: "))
                    blog.view_post(index)
            
            elif choice == "4":
                blog.list_posts()
                if blog.posts:
                    index = int(input("请输入要删除的文章编号: "))
                    blog.delete_post(index)
            
            elif choice == "5":
                print("感谢使用博客系统!")
                break
            
            else:
                print("无效的选择,请重新输入")
        
        except ValueError:
            print("请输入有效的数字")
        except Exception as e:
            print(f"发生错误: {e}")

if __name__ == "__main__":
    main()

恭喜你完成了进阶篇的学习!现在你已经掌握了Python的核心概念,能够编写更加复杂和结构化的程序了。继续加油,高阶篇在等着你!

后续我将会继续分享本系列教程最后一篇《高阶篇》。敬请期待!

关注"大虫小呓"(全网同名),第一时间获得更多技术干货。

相关推荐
TT-Kun2 小时前
PyTorch基础——张量计算
人工智能·pytorch·python
天若有情6737 小时前
【python】Python爬虫入门教程:使用requests库
开发语言·爬虫·python·网络爬虫·request
IT北辰7 小时前
用Python+MySQL实战解锁企业财务数据分析
python·mysql·数据分析
Lucky高7 小时前
selenium(WEB自动化工具)
python
秃然想通7 小时前
掌握Python三大语句:顺序、条件与循环
开发语言·python·numpy
骇客野人8 小时前
使用python写一套完整的智能体小程序
开发语言·python
山楂树の9 小时前
模型优化——在MacOS 上使用 Python 脚本批量大幅度精简 GLB 模型(通过 Blender 处理)
python·macos·3d·图形渲染·blender
云霄IT9 小时前
python之使用ffmpeg下载直播推流视频rtmp、m3u8协议实时获取时间进度
python·ffmpeg·音视频
沐风清扬10 小时前
Win10下python环境变量呼出微软应用商店
开发语言·python
java1234_小锋10 小时前
【NLP舆情分析】基于python微博舆情分析可视化系统(flask+pandas+echarts) 视频教程 - 微博评论数据可视化分析-点赞区间折线图实现
python·自然语言处理·flask