为什么写这篇:Python 是少有的"零基础一周能上手、一年能进工程"的语言。但"上手"和"工程"之间有一道坎——缩进、动态类型、包管理、虚拟环境。这篇用一篇的篇幅把这些一并讲完,让你能从 print("hello") 平滑过渡到 pip install -r requirements.txt。
适用读者:完全没接触过 Python 的初学者;或用过 Python 但没系统管理过依赖/环境的开发者。
基线版本:本文示例基于 Python 3.13(2024-10-07 正式发布)与 pyenv 2.6.27。3.13 引入了实验性 JIT 编译器、改进的交互式 REPL(Py 3.13 起 python 默认带颜色高亮与多行编辑)、typing 模块的进一步类型化语义等;但本文语法示例与 3.10+ 完全兼容,向下覆盖到 3.8 仍可运行。
目录
- Python 程序结构
- 类型与变量
- 运算符
- 字符串
- 列表
- 流程控制
- 虚拟环境:pyenv + venv
- pip 与国内镜像
- 常见坑
1. Python 程序结构
Python 用缩进表示代码块,不用 {}。同一代码块的语句必须缩进相同空格数(约定 4 空格)。
1
2
3
| 当语句以冒号 : 结尾时,缩进的语句视为代码块
按照约定俗成的惯例,应该始终坚持使用 4 个空格的缩进
Python 程序是大小写敏感的,如果写错了大小写,程序会报错
|
一个完整的程序示例(PEP 8 风格):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| #!/usr/bin/env python3
"""this is a test module.""" # 模块文档字符串(双/单引号皆可)
import sys # 模块导入
debug = True # 全局变量
class FooClass: # 类定义(Py 3 不用写 object)
"""Foo class"""
pass
def test(): # 函数定义
"""test func"""
foo = FooClass()
if debug:
print("run test()")
if __name__ == "__main__": # 主程序入口
test()
|
| 元素 | 作用 |
|---|
__init__.py | 标识一个文件夹是包(Python 3.3+ 命名空间包可省略,但显式写更稳) |
import | 导入模块/包 |
if __name__ == "__main__" | 直接执行时为 True,被 import 时为 False——模块既可作库也可作脚本 |
文档字符串("""...""") | 写模块/类/函数的官方注释,可用 help() / __doc__ 查 |
为什么模块入口要写 if __name__ == "__main__":避免 import 时副作用自动执行。一个文件既能 python file.py 直接跑,也能 import file 复用。
Py 3.13 的小升级:解释器现在会在交互模式下自动给 python 命令加颜色高亮(--no-color 关闭),并把 REPL 默认行为改成了"多行粘贴友好"——以前在 >>> 提示符粘贴带缩进的代码块经常乱,现在会自动识别和续行。
2. 类型与变量
2.1 基本类型
1
2
3
4
5
| 整数(如 2、4、20)的类型是 int —— 任意精度,不会溢出
带小数(如 5.0、1.6)的类型是 float —— 底层 IEEE-754 双精度
复数后缀 j 或 J:3 + 5j
Decimal、Fraction:高精度 / 精确分数场景
bool 是 int 的子类:True == 1, False == 0
|
2.2 变量赋值
1
2
| 等号(=)用于给变量赋值
如果变量未定义(即未赋值),使用该变量会提示 NameError
|
Python 是动态类型——变量无类型,值才有类型:
1
2
3
| x = 10 # x 是 int
x = "hello" # x 现在是 str——OK,python 允许
x = [1, 2, 3] # x 现在是 list——也 OK
|
动态类型的代价:大型项目里"传错类型"只有运行时才发现。解法:用 type hint + mypy(x: int = 10),在 IDE / 静态检查阶段拦截。Python 3.13 把 typing 模块的运行时开销进一步降低,类型注解对启动速度的影响可忽略。
3. 运算符
| 运算 | 运算符 | 说明 |
|---|
| 除法 | / | 永远返回 float(4 / 2 == 2.0) |
| 整除 | // | 向下取整,返回 int(如果两边都是 int) |
| 取余 | % | 7 % 3 == 1 |
| 乘方 | ** | 2 ** 10 == 1024 |
| 矩阵乘 | @ | 3.5+ 引入,配合 numpy 用 |
1
2
3
4
5
6
7
8
9
10
| >>> 7 / 2
3.5
>>> 7 // 2
3
>>> 7 % 2
1
>>> 2 ** 10
1024
>>> -7 // 2 # 整除是"向下"取整(向 -∞)
-4
|
整除负数是"向 -∞ 方向取整",不是"截断":-7 // 2 == -4 而不是 -3。需要"截断"就用 int(a / b)。
4. 字符串
4.1 字面量与转义
1
2
3
4
5
6
| s1 = 'hello' # 单引号
s2 = "hello" # 双引号——和单引号完全等价
s3 = "he\"llo" # 反斜杠转义
s4 = r"C:\new\test" # 原始字符串,前缀 r,反斜杠不转义
s5 = """line1
line2""" # 三引号支持多行,行结束符会保留
|
| 字面量前缀 | 含义 | 典型场景 |
|---|
r"..." | 原始字符串,反斜杠不转义 | 正则、文件路径 |
b"..." | 字节串(bytes) | 二进制协议、文件 IO |
f"..." | 格式化字符串(Py 3.6+) | 拼字符串 + 变量 |
R"..." / B"..." | 与 r / b 等价 | 见惯就行 |
1
2
3
| # f-string 拼变量
name = "Python"
print(f"hello {name}! 1 + 1 = {1 + 1}") # hello Python! 1 + 1 = 2
|
原始字符串 r"…" 的常见坑:末尾不能放奇数个反斜杠——r"\" 是非法的。规避方法:把最后一个 \ 单独写 '\\',或者用普通字符串拼。
4.2 拼接、索引、切片
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| s = "hello world"
# 拼接
"hi" + " " + "everyone" # "hi everyone"
"hi" * 3 # "hihihi"
# 索引(从 0 开始;负数从右开始)
s[0] # 'h'
s[-1] # 'd'(最后一个)
s[-2] # 'l'(倒数第二个)
# 切片(左闭右开)
s[0:5] # "hello"
s[6:] # "world"
s[:5] # "hello"
s[::2] # "hlowrd"(步长 2)
s[::-1] # "dlrow olleh"(反转)
|
字符串不可变——s[0] = 'H' 报错。要改字符只能新建:s = 'H' + s[1:]。
4.3 常用内置方法
1
2
3
4
5
6
7
8
9
10
11
12
13
| s = "Hello, World!"
s.lower() # "hello, world!"
s.upper() # "HELLO, WORLD!"
s.strip() # 去首尾空白
s.split(",") # ["Hello", " World!"]——按分隔符切成列表
",".join(["a","b"]) # "a,b"——列表拼成字符串
s.replace("World", "Python") # "Hello, Python!"
s.find("World") # 7——子串位置;找不到返回 -1
"World" in s # True——子串判断
len(s) # 13——长度
s.startswith("He") # True
s.endswith("!") # True
|
5. 列表
列表是 Python 最常用的容器——有序、可变、类型可混。
1
2
3
| fruits = ["apple", "banana", "cherry"]
numbers = [1, 2, 3, 4, 5]
mixed = [1, "two", 3.0, [4, 5]] # 允许混类型(但不推荐)
|
5.1 增删改查
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| fruits = ["apple", "banana", "cherry"]
# 查
fruits[0] # "apple"
fruits[-1] # "cherry"
fruits[0:2] # ["apple", "banana"]——切片返回新列表
# 改
fruits[1] = "blueberry"
# 增
fruits.append("date") # 末尾追加
fruits.insert(1, "avocado") # 在索引 1 处插入
fruits.extend(["elderberry"]) # 末尾追加多个(合并可迭代对象)
# 删
fruits.remove("banana") # 按值删(只删第一个)
popped = fruits.pop() # 删末尾,返回被删元素
popped = fruits.pop(0) # 按索引删
del fruits[0] # 按索引删(不返回)
fruits.clear() # 清空
|
5.2 切片赋值
切片赋值可以改变列表大小——这是 Python 列表的独门技能:
1
2
3
4
| nums = [1, 2, 3, 4, 5]
nums[1:3] = [20, 30, 40] # [1, 20, 30, 40, 4, 5]
nums[1:4] = [] # [1, 4, 5]——切片清空
nums[:] = [] # []——清空整个列表
|
5.3 常用方法
1
2
3
4
5
6
7
8
9
| nums = [3, 1, 4, 1, 5, 9, 2, 6]
len(nums) # 8
nums.sort() # 就地排序,返回 None
nums.reverse() # 就地反转
nums.count(1) # 2——统计 1 出现次数
nums.index(9) # 5——首次出现位置
nums.copy() # 浅拷贝(等价于 nums[:])
new = sorted(nums) # 不改原列表,返回新列表
|
坑:nums.sort() 返回 None!新手常写 sorted_nums = nums.sort() 然后 print(sorted_nums) 打印 None。正确做法:要保留原列表就用 new = sorted(nums),要就地排序就别接返回值。
5.4 推导式(List Comprehension)
1
2
3
4
5
6
7
8
| # 把偶数过滤出来再平方
squares_of_even = [x * x for x in range(10) if x % 2 == 0]
# [0, 4, 16, 36, 64]
# 二维展平
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat = [n for row in matrix for n in row]
# [1, 2, 3, 4, 5, 6, 7, 8, 9]
|
推导式可读性比 map + filter 高,是 Python 圈"地道写法"的标志之一。但不要嵌套超过两层,否则赶紧拆循环。
6. 流程控制
6.1 if / elif / else
1
2
3
4
5
6
7
8
9
10
11
| x = int(input("请输入一个整数:"))
if x < 0:
x = 0
print("Negative changed to zero")
elif x == 0:
print("Zero")
elif x == 1:
print("Single")
else:
print("More")
|
Py 3.10+ 的新写法——match-case:
1
2
3
4
5
6
7
8
| cmd = input("> ")
match cmd:
case "quit" | "exit":
print("bye")
case "help":
print("type quit to leave")
case _:
print(f"unknown: {cmd}")
|
match 不是 switch 的语法糖——它支持模式匹配(解构、类型判断、guard 子句),写解释器 / 解析器时格外好用。
6.2 for 循环
1
2
3
| words = ["cat", "window", "defenestrate"]
for w in words:
print(w, len(w))
|
带索引:
1
2
| for i, w in enumerate(words):
print(i, w)
|
Py 3.13 起 enumerate 的 start 参数更显眼了:
1
2
3
| # 编号从 1 开始
for i, w in enumerate(words, start=1):
print(i, w)
|
6.3 while / break / continue
1
2
3
4
5
6
7
8
| n = 0
while n < 5:
n += 1
if n == 3:
continue # 跳过本次
if n == 4:
break # 跳出循环
print(n)
|
没有 do-while:Python 只用 while + if 实现"至少执行一次"的效果:
1
2
3
4
5
| while True:
user_input = input("> ")
if user_input == "quit":
break
process(user_input)
|
7. 虚拟环境:pyenv + venv
为什么需要虚拟环境:不同项目依赖不同版本的包(django 2.x vs django 4.x),共用全局环境会冲突。虚拟环境给每个项目一份独立的 site-packages。
7.1 pyenv:管理 Python 版本
pyenv 是社区里最主流的多版本 Python 管理工具(macOS / Linux 原生支持,Windows 建议用 pyenv-win)。
1
2
3
4
5
6
7
8
9
10
11
12
| # 安装 pyenv
curl -fsSL https://pyenv.run | bash
# 配置 shell(zsh 举例)
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc
echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zshrc
echo 'eval "$(pyenv init - zsh)"' >> ~/.zshrc
source ~/.zshrc
# 验证
pyenv -v
# pyenv 2.6.27
|
装一个具体的 Python 版本(3.13 在 2024-10-07 发布后,pyenv 数小时内就支持了):
1
2
3
4
5
6
7
8
9
| # 查可安装的版本
pyenv install --list | grep "3\."
# 安装具体版本
pyenv install 3.13.13
pyenv uninstall 3.13.13
# 查看已装的所有版本
pyenv versions
|
虚拟环境插件:
1
2
3
4
| git clone https://github.com/pyenv/pyenv-virtualenv.git \
~/.pyenv/plugins/pyenv-virtualenv
echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.zshrc
source ~/.zshrc
|
创建 / 激活虚拟环境:
1
2
3
4
5
6
7
8
9
| # 用 3.13.13 创建一个名为 myenv 的虚拟环境
pyenv virtualenv 3.13.13 myenv
# 激活
pyenv activate myenv
# 退出
pyenv deactivate
# 删除
pyenv uninstall myenv
|
切换当前目录默认版本(pyenv local 会在目录里写一个 .python-version):
1
2
3
4
| pyenv local 3.13.13 # 当前目录默认 3.13.13
pyenv local --unset # 取消目录级
pyenv global system # 取消全局设置
pyenv shell --unset # 取消 shell 临时设置
|
pyenv 适合 macOS / Linux。Windows 下推荐用 pyenv-win(用法几乎一致)或直接用 python -m venv(标准库自带,跨平台更稳)。
7.2 venv:标准库内置(跨平台)
不想装 pyenv?Python 自带的 venv 就够用,3.13 起默认就是 venv 而不是被废弃的 virtualenv。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| # 创建虚拟环境
python3 -m venv ~/.myenv
# 激活
# macOS / Linux:
source ~/.myenv/bin/activate
# Windows (PowerShell):
~/.myenv/Scripts/Activate.ps1
# Windows (cmd):
~/.myenv\Scripts\activate.bat
# 退出
deactivate
|
激活后 python 和 pip 都指向虚拟环境里的,包只装在 myenv/ 里,不污染全局。
Py 3.13 的 venv 改进:默认创建的 venv 不再包含 pip,需要用 python -m ensurepip --upgrade 引导安装。这是 PEP 668 推动"显式依赖"的一部分——避免 venv 一创建就拉一堆默认包。
7.3 项目级:用 pyenv + venv 协同
最工程化的做法:pyenv 管 Python 解释器版本,venv 管项目依赖。
1
2
3
4
5
| # 在项目目录里
pyenv local 3.13.13 # 该目录自动用 3.13.13
python -m venv .venv # 创建 venv(推荐 .venv 而不是 .env)
source .venv/bin/activate
pip install -r requirements.txt
|
把 .venv/ 写进 .gitignore:
1
2
3
| .venv/
__pycache__/
*.pyc
|
8. pip 与国内镜像
8.1 基础命令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| # 引导并升级 pip(Py 3.13 之后 venv 默认不带 pip)
python -m ensurepip --upgrade
python -m pip install --upgrade pip
# 装包
pip install requests
pip install requests==2.31.0 # 指定版本(requests 2.31.0 发布于 2023-05-22)
pip install -r requirements.txt # 批量装
# 查包
pip list
pip show requests
# 导出依赖
pip freeze > python_modules.txt
# 卸载
pip uninstall requests
pip freeze | xargs pip uninstall -y # 一键全卸
pip uninstall -r python_modules.txt -y # 按文件卸
|
8.2 国内镜像(强烈推荐)
直连 PyPI 在国内经常超时,挂个国内源秒装:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| # 清华源
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
# 阿里源
pip config set global.index-url https://mirrors.aliyun.com/pypi/simple
# 腾讯源
pip config set global.index-url https://mirrors.cloud.tencent.com/pypi/simple
# 豆瓣源
pip config set global.index-url https://pypi.douban.com/simple/
# 网易源
pip config set global.index-url https://mirrors.163.com/pypi/simple/
pip config list
# Writing to C:\Users\Administrator\AppData\Roaming\pip\pip.ini
|
设置后会写入 ~/AppData/Roaming/pip/pip.ini(Windows)或 ~/.config/pip/pip.conf(macOS / Linux):
1
2
3
4
| [global]
index-url = https://mirrors.aliyun.com/pypi/simple
[install]
trusted-host = mirrors.aliyun.com
|
配镜像后必须关掉代理——很多公司开发网络走代理,配了国内源反而走代理到国外、慢得离谱。unset http_proxy && unset https_proxy(macOS / Linux)或 PowerShell Remove-Item Env:http_proxy(Windows)后再装包。
8.3 代理场景
1
2
3
| # Windows cmd 临时挂代理
set http_proxy=http://127.0.0.1:1081
set https_proxy=http://127.0.0.1:1081
|
1
2
3
| # macOS / Linux 临时挂代理
export http_proxy=http://127.0.0.1:1081
export https_proxy=http://127.0.0.1:1081
|
装包失败先看这个顺序:(1) 是不是公司代理挡了?(2) 是不是 SSL 证书问题?(3) 是不是镜像源 5xx 临时挂了?三步都排完再怀疑代码。
8.4 用 pipx 装命令行工具
有些工具是命令行型的(black、ruff、httpie),用 pip 装到全局会污染 site-packages,推荐用 pipx:
1
2
| pipx install black # 隔离环境装,自动加到 PATH
pipx upgrade-all
|
9. 常见坑
9.1 缩进错误
1
2
3
| if x:
print("a")
print("b") # IndentationError:缩进不一致
|
规避:编辑器装 Python 扩展自动缩进 4 空格,混用 Tab / 空格是禁忌。
9.2 可变默认参数
1
2
3
4
5
6
| def add_item(item, bucket=[]): # 坑!
bucket.append(item)
return bucket
add_item(1) # [1]
add_item(2) # [1, 2]——bucket 在函数定义时创建一次,跨调用共享
|
修法:
1
2
3
4
5
| def add_item(item, bucket=None):
if bucket is None:
bucket = []
bucket.append(item)
return bucket
|
Why:Python 默认参数在函数定义时只求值一次,不是每次调用都新建。这是 Python 最经典的设计陷阱。
9.3 浮点比较
1
2
3
4
| >>> 0.1 + 0.2 == 0.3
False
>>> 0.1 + 0.2
0.30000000000000004
|
修法:用 decimal.Decimal 或 math.isclose(a, b):
1
2
| import math
math.isclose(0.1 + 0.2, 0.3) # True
|
9.4 字符串拼接性能
1
2
3
4
5
6
7
| # 反例:循环里用 += 拼字符串
s = ""
for x in range(10000):
s += str(x) # 每次新建对象,O(n²)
# 正解:用 join
s = "".join(str(x) for x in range(10000)) # O(n)
|
9.5 import 顺序
PEP 8 推荐:
- 标准库
- 第三方库
- 本地应用 / 库
每组之间空一行:
1
2
3
4
5
6
7
| import os
import sys
import numpy as np
import requests
from myproject.utils import helper
|
9.6 is vs ==
1
2
3
4
| a = [1, 2, 3]
b = [1, 2, 3]
a == b # True——值相等
a is b # False——不是同一个对象
|
小整数缓存例外:a = 256; b = 256; a is b 可能是 True,因为 CPython 缓存了 [-5, 256] 的小整数。但不要依赖这个,用到 is 的场景几乎都是"判断 None / 哨兵对象"。
9.7 不要用 from module import *
1
| from os import * # 会污染命名空间
|
import * 让代码不可读、不可重构——open() 是 os.open 还是 builtins.open?避免。
小结
一句话总结:Python 的"易学"在语法——缩进代替大括号、动态类型、丰富的内置容器;Python 的"工程难点"在依赖管理——pyenv 管版本、venv 管隔离、pip 管包,配上国内镜像速度起飞。
5 个最常用内置:
1
2
3
4
5
| len(s) # 长度
s.split(",") # 切
",".join(list) # 拼
range(10) # 整数序列
enumerate(list) # 索引 + 值
|
5 个最容易踩的坑:
- 可变默认参数
def f(bucket=[]) → bucket 跨调用共享 - 浮点比较
0.1 + 0.2 != 0.3 → 用 math.isclose - sort 不返回
nums.sort() 返回 None → 要新列表用 sorted(nums) - 缩进混 Tab / 空格 → 编辑器强制 4 空格
- 循环里 += 拼字符串 → 用
"".join(...)
5 个 3.13 时代的新习惯:
- 默认用 f-string,不要再用
% 或 .format() - 路径用
pathlib.Path,不要用 os.path 拼字符串 - 类型注解 + mypy,别只靠运行时
- 数据类
dataclass 替代手写 __init__ - 依赖锁
pip freeze 进 git,CI / 生产环境必须可复现
2024+ 视角:Python 3.13 JIT 与 free-threading
Python 3.13 关键变化(已在用)
- 实验性 JIT 编译器(
--enable-experimental-jit):简单计算性能 +10-15% - 改进的 REPL:默认带颜色高亮、多行粘贴友好、
exit_code 显示 - GIL 改进:
--disable-gil 实验标志(free-threading 铺垫) - 类型注解改进:
type X = int 类型别名支持 - 弃用
locale.resetlocale():编码问题改用 locale.setlocale(LC_ALL, "") 配合 open(..., encoding="utf-8")
Python 3.14(2025-10 计划)核心变化
- PEP 779:Free-Threaded Python 官方支持(GIL 可移除)
- PEP 750:Template Strings(
t"..." 模板字符串) - PEP 649:延迟求值注解(注解默认不求值,启动更快)
- PEP 761:PyPI 签名归档格式更新
Free-Threading 时代的 Python 并发
1
2
3
4
5
6
7
| # 装 free-threaded Python
python3.14t
# 检查 GIL 是否启用
python -c "import sys; print(sys.flags.gil)"
# -1 = 启用 GIL
# 0 = 禁用 GIL(free-threading)
|
影响:
- CPU 密集型:终于可以用多线程跑满多核
- 生态兼容:numpy / pandas / requests 都需要更新
- AI / 数值计算:巨大收益(不再需要 multiprocessing)
2024+ 数值计算新范式
numpy 2.x
1
2
3
4
5
6
7
8
9
| # numpy 2.0+ 默认 64 位
import numpy as np
# Typed scalars
arr = np.array([1, 2, 3], dtype=np.int32)
print(type(arr[0])) # numpy.int32(不是 Python int)
# String dtype 标准化
arr = np.array(['a', 'b', 'c'], dtype=np.str_)
|
polars 1.x 替代 pandas 部分场景
1
2
3
4
5
6
7
8
9
10
| import polars as pl
# 比 pandas 快 5-30 倍
df = pl.read_parquet("data.parquet")
result = (
df
.filter(pl.col("amount") > 100)
.group_by("category")
.agg(pl.col("amount").sum())
)
|
polars 优势:
- Rust 写的,多线程 + SIMD
- 延迟求值(LazyFrame)
- 内存效率高 50%
- 不依赖 NumPy
pydantic 2.x(Rust 核心)
1
2
3
4
5
6
7
8
9
10
11
| from pydantic import BaseModel, Field
from datetime import datetime
class User(BaseModel):
id: int
name: str = Field(min_length=1, max_length=100)
email: str
created_at: datetime
# 自动验证 + 序列化(Rust 写的核心,速度 +20x)
user = User(id=1, name="Alice", email="alice@example.com", created_at="2024-01-01")
|
Python 异步生态 2024+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| # asyncio + uvloop(替代默认事件循环)
import asyncio
import uvloop
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
# FastAPI 0.110+(主流 Web 框架)
from fastapi import FastAPI
app = FastAPI()
@app.get("/users/{user_id}")
async def get_user(user_id: int):
return {"id": user_id, "name": "Alice"}
# SQLAlchemy 2.0+ 异步
from sqlalchemy.ext.asyncio import AsyncSession
async with AsyncSession(engine) as session:
result = await session.execute(select(User).where(User.id == user_id))
|
AI / LLM 时代 Python 生态
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| # LangChain 0.3+(LLM 应用框架)
from langchain.chat_models import init_chat_model
from langchain_core.messages import HumanMessage, SystemMessage
model = init_chat_model("gpt-4o", model_provider="openai")
response = model.invoke([
SystemMessage("你是一个严谨的技术写作助手"),
HumanMessage("用一句话解释 GIL 是什么")
])
print(response.content)
# 国产替代
from langchain.chat_models import init_chat_model
qwen = init_chat_model("qwen-plus", model_provider="dashscope")
# 端侧小模型
from llama_cpp import Llama
llm = Llama(model_path="./qwen2.5-7b.gguf", n_ctx=4096)
output = llm("Q: 1+1?\nA:", max_tokens=20)
|
Python 包管理 2024+ 新工具
| 工具 | 特点 | 2024+ |
|---|
| uv(Astral 出品) | 装包比 pip 快 10-100 倍 | 强烈推荐 |
| poetry | 依赖锁定 + 虚拟环境 | 主流企业 |
| pdm | PEP 582 标准 | 国产活跃 |
| rye | 统一 Python + 包管理 | 实验性 |
| hatch | 现代构建系统 | 库作者首选 |
1
2
3
4
5
6
7
| # uv 一行替代 pip / pip-tools / venv / pyenv
curl -LsSf https://astral.sh/uv/install.sh | sh
uv python install 3.13
uv venv
uv pip install -r requirements.txt
uv pip sync requirements.lock
|
2024+ 工具链推荐
1
2
3
4
5
6
7
8
9
10
11
12
13
| 现代 Python 项目
├── 运行时:Python 3.13(3.14 free-threading 实验)
├── 包管理:uv 0.4+(推荐)/ poetry 1.8+
├── 类型检查:mypy 1.13 / pyright 1.1(更快)
├── 格式化:ruff 0.6+(替代 black + isort + flake8)
├── 测试:pytest 8 + coverage
├── 静态分析:ruff + mypy
├── 文档:mkdocs-material 9
├── 异步:asyncio + uvloop
├── Web:FastAPI 0.110+ + SQLAlchemy 2.0
├── 数据:polars 1.x / pandas 2.x
├── AI:LangChain 0.3+ / vLLM / llama-cpp-python
└── 部署:Docker + Uvicorn
|
数据来源: