找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

3914

积分

0

好友

518

主题
发表于 昨天 22:57 | 查看: 4| 回复: 0

TL;DR

  • 拖慢你的不是不会算法,是每天发生 20 次的 ImportError、手写 __init__os.path 拼路径——这些微小摩擦才是真正的效率杀手。
  • 8 个技巧全来自 Python 标准库或一行 pip install,不需要学新框架、不需要重构项目,今天看了明天就能用。
  • python -m 告别导入报错、pathlib 替代 os.pathdataclass 省样板代码、rich 美化调试——把认知资源留给值得思考的问题。

8 个能立刻用上的 Python 开发效率技巧——从 python -m 告别导入报错,到 rich 让调试输出一目了然,再到 dataclasses 省掉一半样板代码。每个技巧都附带可直接复制的代码示例。


01 效果先行

先看一个对比。这是大多数 Python 初学者写的代码:

import os

# 手动拼路径,丑且容易出错
data_dir = os.path.join("project", "data", "2024", "raw")
config_file = os.path.join(data_dir, "config.json")

# 手动计数器
i = 0
items = ["requests", "httpx", "aiohttp"]
for item in items:
    print(f"{i}: {item}")
    i += 1

# 手写 __init__,纯体力活
class APIConfig:
    def __init__(self, url, timeout, retries):
        self.url = url
        self.timeout = timeout
        self.retries = retries

    def __repr__(self):
        return f"APIConfig(url={self.url}, timeout={self.timeout}, retries={self.retries})"

这是改完之后的:

from pathlib import Path

data_dir = Path("project") / "data" / "2024" / "raw"
config_file = data_dir / "config.json"

items = ["requests", "httpx", "aiohttp"]
for i, item in enumerate(items):
    print(f"{i}: {item}")

from dataclasses import dataclass

@dataclass
class APIConfig:
    url: str
    timeout: int
    retries: int

少了快一半代码,可读性反而更高。下面逐个拆解这些技巧。


02 场景定义

我写了 4 年多 Python,发现一个规律:真正拖慢开发速度的,不是你不会某个算法,而是一堆“小不爽”在消耗你

比如:

  • 脚本跑起来报 ImportError,查了半天发现是路径写法不对
  • 打印了一坨调试信息,眼睛看花了才找到关键字段
  • 每次新建数据类都要手写 __init__,像在做填空题
  • os.path 拼路径,代码看着像正则表达式

这些不是大问题。但当它们每天出现 20 次,一周就是 140 次微小摩擦。

下面这 8 个技巧,每一个解决一类“小不爽”。不需要学新框架,不需要重构整个项目——今天看了明天就能用。


03 环境搭建

本文所有示例基于 Python 3.9+,大部分特性 3.7+ 就支持。唯一需要额外安装的库是 rich

pip install rich

其余都是 Python 标准库自带,不用装任何东西。


04 核心技巧

技巧 1:用 python -m 运行脚本,告别导入报错

新手习惯这样跑脚本:

python app/main.py

项目一大,迟早会撞上这个报错:

ImportError: attempted relative import with no known parent package

换一种方式:

python -m app.main

Python 会把你的代码当作正经模块来执行,导入路径自动对齐项目根目录。越是多人协作、多层目录的项目,这个习惯越值钱。

我见过一个实习生因为这个报错 debug 了两个小时,最后改了一行命令就好了。


技巧 2:用 rich 让调试输出像 IDE 一样清晰

标准 print() 够用,但丑。当你调试嵌套字典或复杂 JSON 时,满屏黑白文字很难一眼定位问题。

from rich import print

data = {
    "user": "小王",
    "requests": 142,
    "errors": [
        {"code": 503, "msg": "Service Unavailable", "count": 12},
        {"code": 429, "msg": "Rate Limited", "count": 7},
    ],
}
print(data)

输出自动带上语法高亮和格式化缩进,嵌套结构一目了然。

再加一行:

from rich.traceback import install
install()

之后所有异常的回溯信息都会变成彩色分层的格式。这看起来像“锦上添花”,实际上可读的调试信息直接降低认知负荷——而认知负荷正是隐藏的生产力杀手。


技巧 3:用 pathlib 替代 os.path

老项目中到处都是这种写法:

import os

config_path = os.path.join("project", "config", "app.yaml")
if os.path.exists(config_path):
    content = open(config_path).read()

pathlib 是 Python 3.4 就有的标准库,但很多人一直没用起来:

from pathlib import Path

config_path = Path("project") / "config" / "app.yaml"
if config_path.exists():
    content = config_path.read_text()

/ 拼路径比 os.path.join() 直观太多。而且 Path 对象自带 read_text()write_text()read_bytes()glob() 等方法,不用再调 open() 了。

# 遍历目录下所有 CSV 文件
for csv_file in Path("data").glob("*.csv"):
    print(csv_file.read_text())

你一旦用习惯,再回去看 os.path 会觉得像在用 Java 写文件操作。


技巧 4:用 dataclasses 消灭样板代码

如果你的类主要就是存数据,手写 __init__ 纯属体力劳动:

from dataclasses import dataclass

@dataclass
class LLMConfig:
    model: str = "claude-sonnet-4-6"
    temperature: float = 0.7
    max_tokens: int = 4096

三行搞定。自动获得 __init____repr____eq__

这在 API 开发、配置管理、ETL 管道里特别实用——省掉的不只是打字,更是心智开销。你一眼就能看清这个类有哪些字段、什么类型、默认值是多少。


技巧 5:enumerate() 和列表推导式

还在这样写?

i = 0
for name in names:
    print(i, name)
    i += 1

Python 标准库十年前就替你解决了:

for i, name in enumerate(names):
    print(i, name)

同理,把 4 行映射写成 1 行:

# 之前
results = []
for n in numbers:
    results.append(n * 2)

# 之后
results = [n * 2 for n in numbers]

但记住一句话:如果你的推导式看起来像被熬夜巫师写出来的数学证明,换回普通 for 循环。六个月后的你会感谢现在的你。


技巧 6:永远用 if __name__ == "__main__" 保护入口

这不是“高级技巧”,但大量 Python 开发者跳过它:

def main():
    # 你的脚本逻辑
    process_data()
    generate_report()

if __name__ == "__main__":
    main()

为什么重要?因为早晚有一天你会:

  • 把这个文件 import 到别处复用
  • 给它写测试
  • 重构时把功能拆到不同模块

没有这个守卫,import 时脚本可能意外执行——触发 API 调用、写数据库、发邮件。凌晨两点被报警叫醒,通常就是因为这种“小疏忽”。

别问我怎么知道的。


技巧 7:用 time.perf_counter() 做性能测试

很多人测代码性能顺手写:

import time

start = time.time()
# ... 你的代码 ...
print(time.time() - start)

time.time() 是看钟用的,不适合 benchmark。它精度不够,而且受系统时间调整的影响。

正确做法:

from time import perf_counter

start = perf_counter()
# ... 你的代码 ...
elapsed = perf_counter() - start
print(f"耗时: {elapsed:.4f} 秒")

perf_counter() 专为性能测量设计,精度更高、不受系统时间跳变影响。你在优化 API 响应、数据处理管道时,这 0.001 秒的精度差别会非常关键——尤其是当那段代码在生产环境跑了 40 万次。


技巧 8:用 watchdog 实现热重载

“改一行代码 → 切到终端 → 重新运行 → 看结果 → 再改一行”这个循环,每天至少重复几十次。

pip install watchdog

然后:

watchmedo auto-restart --patterns="*.py" -- python your_script.py

保存文件后脚本自动重启。尤其在调试 API 调用或数据处理流程时,这个体验像开挂一样。

等你习惯了这个节奏,手动重跑脚本会感觉像在用 2006 年的翻盖手机。


05 踩坑提醒

这 8 个技巧都不难,但有几点要注意:

  • python -m 的路径写法:用分隔而非斜杠。app/main.pyapp.main,写错了会报 No module named
  • dataclasses 的可变默认值陷阱:不要在字段默认值里直接用 []{},用 field(default_factory=list)
  • 列表推导式不要写太深:超过 2 层嵌套或带多个 if 条件时,果断换普通循环。同事会感谢你的。
  • perf_counter() 的返回值:单位是秒,但起点不保证是某个固定时间点——只用来算差值。

06 完整代码 + 下一步

把以上技巧串起来的日常开发模板:

"""日常 Python 脚本模板 —— 每个新项目从这里开始"""
from pathlib import Path
from time import perf_counter
from dataclasses import dataclass
from rich import print
from rich.traceback import install

install()  # 全局美化异常回溯

@dataclass
class Config:
    data_dir: str = "data"
    output_dir: str = "output"

def process_files(config: Config) -> list[Path]:
    """读取 data_dir 下所有 CSV,返回文件路径列表"""
    data_path = Path(config.data_dir)
    if not data_path.exists():
        raise FileNotFoundError(f"目录不存在: {config.data_dir}")
    return list(data_path.glob("*.csv"))

def main():
    start = perf_counter()

    config = Config()
    files = process_files(config)
    for i, f in enumerate(files):
        print(f"[{i}] {f.name}")

    print(f"\n[green]处理完成,共 {len(files)} 个文件,耗时 {perf_counter() - start:.3f}s[/green]")

if __name__ == "__main__":
    main()

把这个模板保存下来,下次新建 Python 脚本时直接复制,省掉环境初始化的“冷启动”时间。

下一步可以玩什么?

  • rich 的进度条(rich.progress)接入你的数据处理循环
  • watchdog 监听文件目录,自动触发数据处理流程
  • dataclasses 换成 pydantic.BaseModel,给配置类加上自动校验

这些技巧本身很小。但每天少踩的坑、少写的样板代码、少耗的认知资源,一个月下来就是质变。

真正的效率不是“敲键盘更快”——是把精力留给值得思考的问题。如果你也有自己总结的效率秘笈,不妨来 云栈社区 和大家一起切磋。




上一篇:漏洞管理与补丁治理(上):漏洞扫描已做,风险为何不降?
下一篇:ModuleNotFoundError?五种 Python 跨目录导入彻底解决
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-6-27 03:37 , Processed in 0.601561 second(s), 39 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表