写给有 3-5 年+ PHP 经验、想快速上手 Python 的程序员。不教基础编程概念,只讲 PHP 到 Python 的关键差异和避坑指南。
为什么写这个系列?
我写了 10 年 PHP,从 ThinkPHP 到 Laravel,从传统电商到 Shopify 独立站。2026 年,AI 浪潮来了,Python 成了绕不开的语言——大模型 API、ComfyUI 自动化、数据分析,全都是 Python 生态。
我给自己定了 5 天速成 Python 的计划,不是从零学编程,而是用 PHP 的直觉快速映射到 Python。5 天后,我成功接入了大模型 API、搭建了 FastAPI 服务、自动化了 ComfyUI 图片生成流程。
这个系列就是我这 5 天的学习笔记,专门写给和我一样有 PHP 背景、想快速转型的程序员。
适合谁看:
- 想快速上手 Python 接 AI 项目或做自动化
不适合谁看:
- 想深入学 Python 底层原理的(这个系列是速成实战)
Day 1:语法速通 + 转型避坑
今天的目标很简单:让 PHP 老手快速看懂 Python 代码,并避开最容易踩的坑。
一、环境搭建(30 分钟)
先装 Python。去 https://www.python.org/downloads/ 下载 Python 3.10.x(推荐 3.10.11,这是最后一个有完整 Windows 安装包的 3.10 版本,AI 生态兼容性较好)。
安装时最重要的一步:勾选 “Add python.exe to PATH”。不勾选的话,命令行找不到 python 命令。
装完后打开 CMD 验证:
python --version# 应该输出 Python 3.10.xpip --version# 应该输出 pip 2x.x.x
再装个 VS Code,装上 Python 扩展,就能开始写代码了。
PHP vs Python 环境对照:
💪 所谓万事开头难,能够完成环境搭建,你已经向前迈出了标志性的一步,恭喜! 接下来我们快速过一遍语法,你会发现 PHP 老手学 Python 还是很轻松的。
二、语法速通(2 小时)
2.1 最基础的差异
Python 和 PHP 最大的区别:没有 {},用缩进代替。没有 $,没有 ;。
# ===== 变量:不需要 $ 和类型声明 =====name = "张三"# PHP: $name = "张三";age = 38# PHP: $age = 38;price = 99.9# PHP: $price = 99.9;is_vip = True# PHP: $is_vip = true;# 注意首字母大写items = None# PHP: $items = null;# None 不是 null# ===== 字符串插值 =====greeting = f"你好,我叫{name},今年{age}岁"# PHP: "你好,我叫{$name},今年{$age}岁"# ===== 打印 =====print("Hello World")# PHP: echo "Hello World";print(f"名字:{name}")# PHP: echo "名字:{$name}";
2.2 数据结构:从"一个 array 通吃"到"四种数据结构"
这是 PHP 程序员最大的思维转换。PHP 只有一个 array,Python 有四种:
# ===== 列表 List(对标 PHP 索引数组)=====products = ["假发A", "假发B", "假发C"]products.append("假发D")# PHP: $products[] = "假发D";products[0]# "假发A"len(products)# 4,PHP 用 count($products)# ===== 字典 Dict(对标 PHP 关联数组)=====product = { "name": "渐变卷发", "length": 10, "price": 299.00, "in_stock": True}# PHP: $product = [# "name" => "渐变卷发",# "length" => 10, ...# ];product["name"]# "渐变卷发"product.get("weight", 0)# 安全获取,不存在返回默认值 0# PHP: $product["weight"] ?? 0# ===== 元组 Tuple(不可变的列表)=====position = (100, 200)# 创建后不能修改x, y = position# 解构赋值# ===== 集合 Set(去重)=====tags = {"假发", "美发", "时尚", "假发"}# 自动去重tags.add("新品")
2.3 控制流:for 循环只有 for…in
# ===== if/elif/else =====# 注意:没有 elseif,是 elifprice = 299if price >= 500: discount = 0.7elif price >= 200: discount = 0.85else: discount = 0.95# ===== for 循环(只有 for...in 形式)=====# 遍历列表for product in products: print(product)# 遍历字典for key, value in product.items(): print(f"{key}: {value}")# 带索引遍历# 对标 PHP 的 foreach($arr as $i => $v)for i, product inenumerate(products): print(f"第{i}个:{product}")# ===== try/except(对标 PHP 的 try/catch)=====try: result = 10 / 0except ZeroDivisionError as e: print(f"出错了:{e}")except Exception as e: print(f"其他错误:{e}")finally: print("无论如何都会执行")
2.4 函数:*args 和 **kwargs
# ===== 基本函数 =====def calculate_discount(price, discount=0.8): # 这是文档字符串,类似 PHP 的 PHPDoc """计算折扣价""" return price * discount# 用默认折扣final_price = calculate_discount(299)# 关键字参数final_price = calculate_discount( price=299, discount=0.7)# ===== *args 和 **kwargs(可变参数)=====def print_products(*names, **details): # *names 接收任意数量的位置参数 → tuple # **details 接收任意数量的关键字参数 → dict for name in names: print(f"产品:{name}") for key, value in details.items(): print(f"{key}: {value}")print_products( "假发A", "假发B", brand="瑞贝卡", year=2026)# ===== Lambda 匿名函数 =====# 对标 PHP 的箭头函数 fn() =>double = lambda x: x * 2# PHP: $double = fn($x) => $x * 2;
🎉 语法速通完成! 你已经掌握了 Python 最核心的语法结构。作为 PHP 老手,这些对你来说应该很亲切。接下来我们进入重头戏——PHP 程序员最容易踩的坑,这些坑我可是一个不落地踩过了。
三、PHP → Python 转型避坑指南(重点)
你有多年 PHP 经验,语法不是难点,关键是哪些习惯要改、哪些直觉会骗你。
🔴 坑 1:赋值是引用,不是拷贝
这是 PHP 开发者最容易踩的坑。PHP 数组赋值默认拷贝,Python 列表/字典赋值是引用。
# PHP 直觉:# $a = [1, 2, 3];# $b = $a;# $b[] = 4;# $a 还是 [1, 2, 3],互不影响# Python 实际:a = [1, 2, 3]b = a# b 和 a 指向同一个对象!b.append(4)print(a)# [1, 2, 3, 4] ← a 也被改了!# 要拷贝得显式操作:b = a.copy()# 浅拷贝(最常用)b = a[:]# 切片也是浅拷贝import copyb = copy.deepcopy(a)# 深拷贝(嵌套对象时用)
函数传参也是引用:
def add_product(products, name):# 会修改原始列表!不是拷贝 products.append(name)items = ["假发A"]add_product(items, "假发B")print(items)# ["假发A", "假发B"] ← 被函数改了
记住:数字、字符串、元组是"值类型"(不可变),列表/字典/集合是"引用类型"(可变)。
🔴 坑 2:字符串"0"的真假值不同
# PHP: "0" 是 falsy# if ("0") { echo "yes"; }# else { echo "no"; }# → 输出 "no"# Python: "0" 是 truthy!if "0": # 会执行!非空字符串都是 True print("yes")# Python 的 falsy 值:# None, 0, 0.0, "", [], {}, set(), False# 注意:"0" 不在 falsy 列表里!
如果你从 PHP 搬逻辑过来,涉及 "0" 的判断要特别检查。
🔴 坑 3:缩进就是语法
# PHP 你习惯这样写,缩进无所谓# if ($x > 0) {# $y = 1;# 能跑# }# Python 缩进错了就报错或逻辑错误if x > 0: y = 1# ← 这才对# 用 4 个空格缩进(VS Code 默认)# 别用 Tab,混用空格和 Tab 会报错
🟡 要适应的差异
字符串不可变:
# PHP:# $s = "hello";# $s[0] = "H";# // $s 变成 "Hello"# Python:s = "hello"s[0] = "H"# TypeError! 字符串不能修改# 得创建新字符串:s = "H" + s[1:]# 结果: "Hello"
None 的安全获取:
d = {"name": "假发A"}# 直接访问不存在的 key → 崩d["price"]# KeyError!# 安全获取# 对标 PHP 的 $d["price"] ?? 0d.get("price", 0)# 不存在返回 0,不崩
变量未定义直接崩:
# PHP:未定义变量自动变 null# echo $undefined_var;# → 输出空,能跑# Python:未定义直接报错print(undefined_var)# NameError!
Python 对"不存在"的态度是立刻崩溃,不会静默通过。这是好事。
四、Python 独有的优势
🌟 能够阅读到这里,你已经超越了大部分人! 很多读者看到这里就放弃了,但你还在坚持。接下来让我们一起掌握 Python 中特有的列表推导式吧——优雅永不过时~
列表推导式:从 PHP 老手视角彻底搞懂
列表推导式是 Python 最优雅的特性之一,PHP 没有对应语法。很多 PHP 程序员初次看到会觉得"这什么鬼",但一旦掌握就再也回不去了。
核心一句话:列表推导式就是把 for 循环压缩成一行。
语法拆解:固定格式,三个部分
# 固定格式,三个部分:[表达式 for 变量 in 可迭代对象]# 等价于下面的 for 循环:结果 = []for 变量 in 可迭代对象: 结果.append(表达式)
从 for 循环到推导式,一步步看
prices = [100, 200, 350, 500]# 第一步:普通 for 循环# PHP 老手最熟悉的方式discounted = []for p in prices: discounted.append(p * 0.8)# 第二步:压缩成推导式discounted = [p * 0.8 for p in prices]# 结果: [80.0, 160.0, 280.0, 400.0]
对照关系:
p * 0.8 → 原来的 append() 里的表达式for p in prices → 原来的 for 循环头
加条件(if):过滤 vs 变换
这是最容易搞混的地方,记住一个原则:if 的位置决定它是过滤还是变换。
# 过滤:只保留价格大于 200 的expensive = [p for p in prices if p > 200]# 结果: [350, 500]# 变换:大于 200 打 8 折,否则原价result = [ p * 0.8 if p > 200 else p for p in prices]# 结果: [100, 200, 280.0, 400.0]
顺序对比:
# if 在 for 后面 → 过滤(去掉不想要的)[p for p in prices if p > 200]# [350, 500]# if-else 在 for 前面 → 变换(保留所有,但改值)[p * 0.8 if p > 200 else p for p in prices]# [100, 200, 280.0, 400.0]
实用速记公式
# 1. 映射(对每个元素做变换)[表达式 for x in 列表]# 2. 过滤(只保留满足条件的)[x for x in 列表 if 条件]# 3. 映射 + 过滤[表达式 for x in 列表 if 条件]# 4. 条件变换(满足条件用 X,否则用 Y)[X if 条件 else Y for x in 列表]
PHP 对比
products = [ {"name": "假发A", "price": 299}, {"name": "假发B", "price": 459}, {"name": "假发C", "price": 159},]# PHP 写法:# $names = array_map(# fn($p) => $p["name"], $products# );# $expensive = array_filter(# $products, fn($p) => $p["price"] > 300# );# Python —— 更直观:names = [p["name"] for p in products]expensive = [ p for p in products if p["price"] > 300]# 组合:筛选 + 转换一步到位names_of_expensive = [ p["name"] for p in products if p["price"] > 300]# ["假发B"]
学习技巧:写不出来就先写 for 循环
如果你不确定推导式怎么写,先写完整的 for 循环,再压缩:
# 第一步:先写完整的 for 循环result = []for p in products: if p["price"] > 300: result.append(p["name"].upper())# 第二步:对照模板塞进去# 模板:[表达式 for x in 列表 if 条件]result = [ p["name"].upper() for p in products if p["price"] > 300]
先写出来再说,不用逼自己一步到位。写多了自然就记住了。
更多实战例子
# 提取字典列表中的某个字段products = [ {"name": "假发A", "price": 299}, {"name": "假发B", "price": 459},]names = [p["name"] for p in products]# 结果: ["假发A", "假发B"]# 生成序号列表numbers = [i * 10 for i in range(1, 6)]# 结果: [10, 20, 30, 40, 50]# 字符串处理words = ["hello", "world", "python"]upper_words = [w.upper() for w in words]# 结果: ["HELLO", "WORLD", "PYTHON"]# 嵌套推导式(生成二维列表)matrix = [ [i * j for j in range(1, 4)] for i in range(1, 4)]# 结果: [[1,2,3], [2,4,6], [3,6,9]]
💡 列表推导式其实不难,对吧? 记住那个公式,多写几次就变成肌肉记忆了。以后你会发现,Python 里这种"语法糖"到处都是,用习惯了就再也回不去。
with 语句:自动管理资源
# PHP:# $f = fopen("test.txt", "r");# $content = fread($f, filesize("test.txt"));# fclose($f); // 忘了关就泄漏# Python:with open("test.txt", "r") as f: content = f.read()# 出了 with 块自动关闭文件# 数据库连接、网络连接同理
🏆 恭喜!今天最核心的内容已经全部讲完。 你已经掌握了 Python 的基础语法、避坑指南和独有的优雅特性。接下来是速查表,可以收藏起来随时查阅。
五、速查对照表
| | |
|---|
| echo, print | print() |
| $name = "x" | name = "x" |
| $a . $b | f"{a}{b}" |
| [1, 2, 3] | [1, 2, 3] |
| ["k" => "v"] | {"k": "v"} |
| count($arr) | len(arr) |
| substr($s, 0, 3) | s[0:3] |
| explode(",", $s) | s.split(",") |
| in_array($x, $arr) | x in arr |
| json_encode($data) | json.dumps(data) |
| json_decode($s, true) | json.loads(s) |
| curl_init() | requests.get(url) |
| __construct() | __init__() |
| $this->name | self.name |
🎯 终点已经遥遥在望了! 最后做个自检,确认今天的内容都掌握了,就可以安心收工。
六、Day 1 自检清单
完成以下项目,说明 Day 1 过关了:
- [ ] Python 和 VS Code 安装完成
- [ ] 理解 list、dict、tuple、set 四种数据结构
- [ ] 理解
with open() 的文件读写方式 - [ ] 知道赋值是引用,需要拷贝要用
.copy() - [ ] 能不看对照表写出 Python 版的
for 循环和 if 判断
如果都打勾了 → 明天开始 Day 2:HTTP + API 调用
🎊 Day 1 完成!
恭喜你完成了 Day 1 的学习! 作为 PHP 老手,你已经成功跨过了 Python 的第一道门槛。
回顾一下今天你掌握了什么:
- ✅ 3 个高频避坑点(引用拷贝、"0"真假值、缩进语法)
- ✅ Python 独有的优雅特性(列表推导式、with 语句)
这些都是你以后写 Python 的基石。 明天我们学 Python 的网络请求,你会发现 requests 库比 PHP 的 curl 简单 10 倍,写起来特别爽。
明天见
Day 1 就到这里。明天我们学 Python 的网络请求,你会发现 Python 的 requests 库比 PHP 的 curl 简单 10 倍。
如果你也是 PHP 转 Python,欢迎在评论区聊聊你的转型经历。有问题也可以留言,我看到都会回复。
系列文章:
- Day 2:HTTP 请求 + JSON + API 调用
- Day 3:大模型 API 接入(OpenAI/文心一言/通义千问)
- Day 5:综合实战——ComfyUI 自动化工具集
作者是 10 年 PHP 开发者,正在转型 Python + AI 方向。本系列是个人学习笔记,如有错误欢迎指正。