PyPython 的技术记录
A PYTHON NOTEBOOK

把问题解决,
把过程记下来。

关于 Python 的学习、尝试与日常实践。
从一小段代码开始,积累可以再次使用的经验。

阅读技术笔记 ↓
● ● ● notebook.py
# 一次学习,一点积累
from pathlib import Path

notebook = Path("今天的收获.txt")
notebook.write_text(
    "让代码更清晰一点。",
    encoding="utf-8"
)

技术笔记

4 篇记录 · 持续积累
Python 技术记录

理解 Python 的装饰器机制

本文深入解析 Python 装饰器的核心概念,探讨其基于闭包和高阶函数的实现原理。通过剖析 functools.wraps 的作用及带参数装饰器的构建方法,帮助开发者掌握代码复用与逻辑分离的技巧,提升程序的可维护性与优雅度。

阅读全文

在 Python 编程实践中,装饰器是一种强大且优雅的语法糖,它允许我们在不修改原有函数源代码的前提下,动态地扩展函数的功能。这一机制的核心在于 Python 将函数视为一等公民,即函数可以作为参数传递、作为返回值返回,以及被赋值给变量。装饰器本质上是一个高阶函数,它接收一个函数作为输入,并返回一个新的函数作为输出。这种设计模式极大地促进了代码的模块化,使得日志记录、权限校验、性能监控等横切关注点能够从业务逻辑中剥离出来,从而保持核心代码的简洁与专注。

要真正理解装饰器,必须掌握闭包的概念。当内部函数引用了外部作用域中的变量时,即使外部函数已经执行完毕,这些变量依然会被保留在内存中,供内部函数使用。装饰器正是利用这一特性,在包装函数中捕获原始函数,并在调用包装函数时插入额外的逻辑。然而,简单的装饰器会改变原始函数的元数据,如名称和文档字符串,这可能导致调试困难或依赖元数据的库无法正常工作。为了解决这个问题,标准库提供了 functools.wraps 装饰器,它能自动将原始函数的属性复制到包装后的函数上,确保行为的一致性。

此外,带参数的装饰器进一步增强了灵活性。这类装饰器通常由三层嵌套函数构成:最外层接收装饰器参数,中间层接收被装饰的函数,最内层则是实际执行的包装逻辑。这种结构虽然增加了复杂性,但赋予了开发者在应用装饰器时配置行为的能力,例如设置重试次数或缓存过期时间。在实际开发中,合理使用装饰器不仅能减少重复代码,还能使程序结构更加清晰。需要注意的是,过度使用多层装饰器可能会增加栈深度,影响性能或导致异常追踪变得复杂,因此应在可读性与功能性之间寻找平衡。掌握装饰器是进阶 Python 开发的必经之路,它体现了 Python 语言对简洁性和表达力的追求。

import functools
import time

def timer(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        start_time = time.perf_counter()
        result = func(*args, **kwargs)
        end_time = time.perf_counter()
        print(f"Function {func.__name__} executed in {end_time - start_time:.4f} seconds")
        return result
    return wrapper

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

slow_function()

本文由 AI 自动生成,尚未经人工审校;请结合官方文档验证。

标准库

用 pathlib,把文件路径写清楚

从拼接字符串到操作路径对象,让日常文件处理更容易阅读和维护。

阅读全文

处理文件时,可以把路径当作对象,而不是自己拼接斜杠。pathlib 是 Python 标准库的一部分。Path 对象支持使用 / 运算符连接路径片段,也提供读取、写入和遍历目录的方法。

下面的例子在当前工作目录下创建 notes 文件夹,再写入并读取一段中文。显式指定 UTF-8 编码,可以减少不同系统默认编码带来的差异。

注意:write_text 会覆盖同名文件的原有内容。处理重要数据前,请先确认目标路径。相对路径以程序启动时的工作目录为基准,而不一定是脚本所在目录。

from pathlib import Path

folder = Path.cwd() / 'notes'
folder.mkdir(parents=True, exist_ok=True)
file = folder / 'hello.txt'
file.write_text('你好,Python!', encoding='utf-8')
print(file.read_text(encoding='utf-8'))
数据处理

用 Counter 统计重复出现的元素

几行代码完成计数,适合整理标签、日志类别和简单统计。

阅读全文

统计列表中每个元素出现了多少次,可以使用 collections.Counter。它接收可迭代对象,并把元素映射到对应的计数。

most_common 方法按计数从高到低返回元素及其数量。示例会得到 python 出现 3 次、sql 出现 2 次。Counter 适合可以完整遍历的数据;对于很大的文件,可以逐行读取并逐步更新计数,避免一次性读入全部原始内容。

from collections import Counter

tags = ['python', 'sql', 'python', 'web', 'sql', 'python']
counts = Counter(tags)
for tag, count in counts.most_common(2):
    print(tag, count)
日常实践

读写 JSON 时,保留中文的可读性

明确编码、格式化缩进,让小型配置文件也能整洁易读。

阅读全文

JSON 常用于保存配置和交换结构化数据。Python 的 json 模块能够在字典、列表等对象与 JSON 文本之间转换。

ensure_ascii=False 让中文直接显示在输出文本中;indent=2 为嵌套结构添加缩进。这两个参数改善可读性,不改变数据本身。文件读写仍然需要指定 UTF-8 编码。

读取外部 JSON 时,要处理文件不存在、格式错误等情况,并检查字段类型。不要把密码或 API 密钥写进对外提供访问的 JSON 文件。

import json

settings = {'名称': 'Python 的技术记录', '语言': '中文'}
text = json.dumps(settings, ensure_ascii=False, indent=2)
print(text)
restored = json.loads(text)
assert restored == settings