前端仔快速上手 Python

以前有过一些python的开发经验,但是有个两三年没怎么写过了,最近在做一些AI相关的项目,会频繁使用到python,作为前端仔,不想从头到尾去花大量时间去学习python了,所以打算通过对比前端和python的语法,来快速上手python。这种类比的学习方式除了学习python其实还可以在很多领域使用的。文章除了介绍python快速上手,其实更重要是希望跟大家分享这种快速的学习思路。
小字提醒:这篇分享内容只是快速上手基础入门,并非有多厉害,大佬轻喷。后续我也会在学习过程中不断补充这篇分享的内容
前言
其实python和js非常相似,都是弱类型语言,生态上也有非常多相似的点,我的习惯是只要我在python开发过程中,想要达到某个效果,我都会想以前端的思维去想一遍。
比如,在前端开发的时候,我可以通过nvm快速切换多个node版本,来在不同版本的项目中灵活运行,那么python项目怎么做?答案:pyenv或者conda。
再如:前端引用三方包,通过npm可以管理各种三方模块,那么python项目怎么做?答案:pip。
或者是反向类比,python的列表,字典这些是什么? 其实python的列表就是可以理解为js中的数组,字典就是js中的对象。
这样一类比,其实发现前端仔其实是不需要花大量时间去学习也能够快速上手python的。你完全可以边学边开发。
1. 环境与工具链
1.1 环境安装
前端用 nvm 管理多个 Node.js 版本,Python 生态有两套主流方案分别是内置的venv和anaconda(我习惯性使用anaconda),所以这里先介绍anaconda的安装,个人是不建议直接安装python的,就像作为前端我也不建议直接安装node,而是建议安装nvm之类的版本管理工具。
如果不喜欢使用anaconda的也可以选择使用venv,以下是一些对比内容 

直接从官网下载安装,anaconda有两个版本,一个是完整体版本,一个是迷你版本的,如果不是深度使用,我的建议是下载miniconda就够用了 下载好之后就可以使用以下的命令了
bash
# 创建含指定 Python 版本的环境 等同于nvm中的 nvm install v20.xx.xx 安装版本
conda create -n myenv python=3.12
# 激活环境(类比 nvm use) 等同于 nvm use xxx 版本
conda activate myenv
# 退出环境
conda deactivate
# 列出所有环境 等同于 nvm list
conda env list
# 导出环境(类比 package.json + node 版本锁定)
conda env export > environment.yml
# 从文件恢复环境
conda env create -f environment.yml
注意: 上面的命令有用到nvm来类比,这里还需要补充一下与nvm不同之处,conda是的激活环境是随终端的,比如:当你打开一个终端,执行了 conda activate myenv 之后,当你下次打开,你还是得重新再次激活,是一次性的效果,不像nvm,执行了 nvm use xxx之后,全局的node版本都会进行切换
如果非要类似nvm这样全局设置python的版本,找到conda的安装目录,找到指定版本的python,然后添加上全局变量即可
1.2 核心工具对照表
| Python 生态 | Node.js 生态 | 说明 |
|---|---|---|
python |
node |
运行时 |
pip |
npm |
包管理器 |
conda / pyenv |
nvm / fnm |
版本管理工具 |
pip install xxx |
npm install xxx |
安装依赖包 |
pip uninstall xxx |
npm uninstall xxx |
卸载依赖包 |
pip freeze > requirements.txt |
npm ls --depth=0 |
导出当前已安装的包 |
requirements.txt |
package.json |
项目依赖清单(简单场景) |
pyproject.toml |
package.json |
项目依赖清单(标准场景) |
pip install -r requirements.txt |
npm install |
从清单安装所有依赖 |
python -m venv .venv |
npm install(创建 node_modules) |
初始化项目本地依赖环境 |
.venv/ |
node_modules/ |
项目本地依赖目录 |
python --version |
node --version |
查看运行时版本 |
pip --version |
npm --version |
查看包管理器版本 |
python script.py |
node script.js |
运行脚本 |
python -i |
node (REPL) |
交互式解释器 |
which python |
which node |
查看当前使用的解释器路径 |
1.3 虚拟环境 ↔ node_modules
核心类比:
bash
Node.js: 项目根目录/node_modules/ ← npm install 后生成,本地依赖
Python: 项目根目录/.venv/ ← python -m venv .venv 后生成,本地解释器 + 依赖
差异在于 Python 的虚拟环境不仅隔离依赖,还隔离了 Python 解释器本身和 pip,每个项目拥有完全独立的 Python 副本。
bash
# 创建虚拟环境(类比 npm init + npm install 的效果)
python -m venv .venv
# 激活虚拟环境(Windows)
.venv\Scripts\activate
# 激活虚拟环境(macOS / Linux)
source .venv/bin/activate
# 激活后,which python 会指向 .venv/ 中的 Python
# pip install 的包也只会安装到 .venv/ 中
# 退出虚拟环境
deactivate
前端习惯类比:激活 venv ≈ 进入一个 npm workspaces 子包目录,npm install 只会影响当前 workspace。
2. 基础语法对比
2.1 变量与基本类型
python
# ---------- Python ---------- # ---------- JavaScript ----------
# 变量声明(无需 let/const/var)
name = "hello" # let name = "hello";
count = 42 # let count = 42;
PI = 3.14 # const PI = 3.14;
is_done = True # let isDone = true;
nothing = None # let nothing = null; (None ≈ null)
# 类型检查
type(name) # <class 'str'> # typeof name // 'string'
isinstance(name, str) # True # name instanceof String // false (基本类型)
2.2 字符串
python
# ---------- Python ---------- # ---------- JavaScript ----------
name = "Alice"
f"Hello, {name}!" # `Hello, ${name}!`
"Hello, {}!".format(name) # "Hello, " + name + "!"
# 多行字符串
text = """ # const text = `
多行
文本 # 多行
""" # 文本
# `;
# 常用方法
"hello".upper() # "HELLO" # "hello".toUpperCase()
"HELLO".lower() # "hello" # "HELLO".toLowerCase()
" hi ".strip() # "hi" # " hi ".trim()
"a,b,c".split(",") # ['a','b','c'] # "a,b,c".split(",")
",".join(["a","b","c"]) # "a,b,c" # ["a","b","c"].join(",")
"abc".startswith("a") # True # "abc".startsWith("a")
"abc".endswith("c") # True # "abc".endsWith("c")
"hello" in "hello world" # True # "hello world".includes("hello")
len("hello") # 5 # "hello".length
2.3 数字与布尔
python
# ---------- Python ---------- # ---------- JavaScript ----------
# 运算一致:+ - * / //(整除) % **
10 / 3 # 3.333... # 10 / 3 // 3.333...
10 // 3 # 3 (整除) # Math.floor(10 / 3) // 3
10 % 3 # 1 # 10 % 3 // 1
2 ** 10 # 1024 # 2 ** 10 // 1024
# 布尔(注意大写)
True, False # true, false
not True # False # !true
True and False # False # true && false
True or False # True # true || false
# 布尔判断时的"假值"(Python 更严格)
# 假值: False, None, 0, 0.0, "", [], {}, set(), ()
# 注意: [] 和 {} 在 Python 中为假------直接用 if my_list: 判断
2.4 列表 ↔ 数组
python
# ---------- Python ---------- # ---------- JavaScript ----------
items = [1, 2, 3] # const items = [1, 2, 3];
items[0] # 1 # items[0]
items[-1] # 3 (倒数第一个) # items[items.length - 1]
items[0:2] # [1, 2] (切片) # items.slice(0, 2)
# 常用操作
items.append(4) # [1,2,3,4] # items.push(4)
items.pop() # 4, items 变 [1,2,3] # items.pop()
items.insert(0, 0) # [0,1,2,3] # items.unshift(0)
items.remove(2) # [0,1,3] # 没有直接等价方法,需用 splice+indexOf
len(items) # 3 # items.length
3 in items # True # items.includes(3)
# 列表推导式(Python 最实用的语法糖之一)
[x*2 for x in range(5)] # [0,2,4,6,8] # [0,1,2,3,4].map(x => x*2)
[x for x in range(10) if x % 2 == 0] # [0,2,4,6,8] # 等价于 .filter().map()
2.5 字典 ↔ 对象 / Map
python
# ---------- Python ---------- # ---------- JavaScript ----------
user = { # const user = {
"name": "Alice", # name: "Alice",
"age": 25 # age: 25
} # };
user["name"] # "Alice" # user["name"] 或 user.name
user.get("name") # "Alice" # user?.name
user.get("email", "N/A") # "N/A" # user.email ?? "N/A"
# 遍历
for key in user: # for (const key in user)
print(key, user[key]) # console.log(key, user[key])
for key, val in user.items(): # for (const [key, val] of Object.entries(user))
print(key, val) # console.log(key, val)
# 合并字典
{**a, **b} # Python 3.5+ # { ...a, ...b }
a | b # Python 3.9+ # { ...a, ...b }
# keys / values
user.keys() # dict_keys # Object.keys(user)
user.values() # dict_values # Object.values(user)
2.6 元组 ↔ 不可变数组(readonly tuple)
python
# ---------- Python ---------- # ---------- TypeScript ----------
point = (3, 4) # const point: [number, number] = [3, 4];
x, y = point # 解构赋值 # const [x, y] = point;
# 元组不可变
# point[0] = 5 # ❌ 报错 # point[0] = 5; // JS 数组可以改...
# 单元素元组注意逗号
single = (42,) # 必须加逗号,否则 (42) 只是数字 42
2.7 集合 ↔ Set
python
# ---------- Python ---------- # ---------- JavaScript ----------
tags = {"a", "b", "c"} # const tags = new Set(["a", "b", "c"]);
tags.add("d") # tags.add("d")
"a" in tags # True # tags.has("a")
# 集合运算
a = {1, 2, 3}
b = {2, 3, 4}
a & b # {2, 3} 交集 # 没有内置交集运算
a | b # {1,2,3,4} 并集 #
a - b # {1} 差集 #
2.8 控制流
python
# ---------- Python ---------- # ---------- JavaScript ----------
# if / elif / else
if score >= 90: # if (score >= 90) {
grade = "A" # grade = "A";
elif score >= 80: # } else if (score >= 80) {
grade = "B" # grade = "B";
else: # } else {
grade = "C" # grade = "C";
# }
# 三元表达式
x = "yes" if ok else "no" # const x = ok ? "yes" : "no";
# for 循环(Python 的 for 只迭代,不是 C 风格三件套)
for item in items: # for (const item of items)
print(item) # console.log(item);
for i in range(5): # for (let i = 0; i < 5; i++)
print(i) # console.log(i);
for i, val in enumerate(items): # items.forEach((val, i) => { ... })
print(i, val)
# while
while count > 0: # while (count > 0) {
count -= 1 # count--;
# }
# 没有 do-while,没有 switch-case(Python 3.10 引入 match-case 类似 switch)
match status:
case 200:
print("OK")
case 404:
print("Not Found")
case _: # default
print("Unknown")
2.9 函数
python
# ---------- Python ---------- # ---------- JavaScript ----------
def greet(name): # function greet(name) {
return f"Hello, {name}" # return `Hello, ${name}`;
# }
# 默认参数
def greet(name="World"): # function greet(name = "World") {
return f"Hello, {name}" # return `Hello, ${name}`;
# }
# 可变参数 *args ↔ ...rest
def sum_all(*args): # function sumAll(...args) {
return sum(args) # return args.reduce((a,b) => a+b, 0);
# }
# 关键字参数 **kwargs ↔ 对象解构
def create_user(**kwargs): # function createUser({ name, age } = {}) {
print(kwargs.get("name")) # console.log(name);
# }
# 匿名函数 lambda ↔ 箭头函数
square = lambda x: x * x # const square = x => x * x;
# 常用场景:sort key
items.sort(key=lambda x: x["age"]) # items.sort((a, b) => a.age - b.age);
# 没有 hoisting!函数必须先定义后调用
2.10 异常处理
python
# ---------- Python ---------- # ---------- JavaScript ----------
try: # try {
result = 10 / 0 # const result = 10 / 0;
except ZeroDivisionError as e: # } catch (e) {
print(f"除零错误: {e}") # console.log(`错误: ${e.message}`);
except Exception as e: # }
print(f"其他错误: {e}") # // JS 只能 catch 一个,需 instanceof 区分
else: # // Python 特有的 else:无异常时执行
print("一切正常")
finally: # } finally {
print("无论是否有异常都执行") # console.log("finally");
# }
# 抛异常
raise ValueError("参数错误") # throw new Error("参数错误");
2.11 类
python
# ---------- Python ---------- # ---------- JavaScript ----------
class Animal: # class Animal {
def __init__(self, name): # constructor(name) {
self.name = name # this.name = name;
# }
def speak(self): # speak() {
return f"{self.name}..." # return `${this.name}...`;
# }
# }
class Dog(Animal): # class Dog extends Animal {
def __init__(self, name, breed): # constructor(name, breed) {
super().__init__(name) # super(name);
self.breed = breed # this.breed = breed;
# }
def speak(self): # speak() {
return f"{self.name} 汪汪" # return `${this.name} 汪汪`;
# }
# }
# 所有方法都需要 self 参数(类比 JS 的 this,但显式传递)
# 私有属性约定:前缀 _ 或 __
# self._secret = 1 # 约定私有(类比 JS _secret 约定)
# self.__private = 1 # 名称改写,真正的私有(但能绕过)
3. 模块与包管理
3.1 import ↔ require / import
python
# ---------- Python ---------- # ---------- JavaScript ----------
# 导入整个模块
import os # const os = require("os");
os.path.join("a", "b") # os.path.join("a", "b")
# 导入特定内容
from os import path # const { join } = require("path");
from os.path import join, exists # const { join, exists } = require("path");
# 别名
import numpy as np # const np = require("numpy"); // 不支持原生别名
from math import sqrt as sq # // JS 需手动: const sq = Math.sqrt;
# 导入所有(不推荐,污染命名空间)
from math import * # // JS 中无直接等价
3.2 包管理对照
| Python | Node.js | 说明 |
|---|---|---|
pip install requests |
npm install axios |
安装并写入依赖 |
pip install requests==2.28 |
npm install axios@1.0.0 |
安装指定版本 |
requirements.txt |
package.json (dependencies) |
项目依赖清单 |
pip freeze |
npm ls --depth=0 |
查看已安装的包 |
pip install -r requirements.txt |
npm install |
从清单安装 |
.venv/ |
node_modules/ |
本地依赖目录 |
pip list |
npm list --depth=0 |
列出已安装包 |
pip uninstall requests |
npm uninstall axios |
卸载包 |
3.3 pyproject.toml(现代 Python 项目标准)
前面用 requirements.txt 类比 package.json,但更准确的对标是 pyproject.toml:
toml
# pyproject.toml # package.json
[project] # {
name = "my-project" # "name": "my-project",
version = "1.0.0" # "version": "1.0.0",
dependencies = [ # "dependencies": {
"fastapi>=0.100", # "fastapi": "^0.100",
"uvicorn>=0.23", # "uvicorn": "^0.23"
] # },
#
[project.optional-dependencies] # "devDependencies": {
dev = [ # "pytest": "^7.0",
"pytest>=7.0", # "ruff": "^0.1"
"ruff>=0.1", # }
] # }
[tool.pytest.ini_options] # // jest 配置通常在 jest.config.js 中
testpaths = ["tests"] #
4. 常用标准库速查
Python "自带电池"------标准库比 Node.js 丰富得多,很多时候不需要装第三方包。
4.1 文件与路径操作
| Python(标准库) | Node.js(标准库) |
|---|---|
import os |
require("os") |
os.path.join("a", "b") |
path.join("a", "b") |
os.path.dirname(p) |
path.dirname(p) |
os.path.basename(p) |
path.basename(p) |
os.path.exists(p) |
fs.existsSync(p) |
os.makedirs("a/b", exist_ok=True) |
fs.mkdirSync("a/b", { recursive: true }) |
os.listdir(".") |
fs.readdirSync(".") |
文件读写推荐用 pathlib(Python 3.4+,更现代):
python
from pathlib import Path
# 路径拼接(类比 path.join)
p = Path("src") / "app" / "main.py" # src/app/main.py
# 读写文件
text = Path("file.txt").read_text(encoding="utf-8")
Path("file.txt").write_text("hello", encoding="utf-8")
# 遍历目录(类比 fs.readdirSync recursive)
for f in Path("src").rglob("*.py"):
print(f)
5. 项目结构
5.1 典型项目布局对比
Node.js 项目:
bash
my-project/
├── node_modules/ # 依赖
├── src/
│ ├── routes/
│ ├── services/
│ └── index.js # 入口
├── package.json
├── .env
├── .gitignore
└── README.md
Python 项目:
bash
my-project/
├── .venv/ # 依赖(类比 node_modules)
├── src/ # 源码(或用包名)
│ ├── __init__.py # 标识为包(类比 package.json 的 "main" + ESM)
│ ├── routes/
│ │ ├── __init__.py
│ │ └── users.py
│ ├── services/
│ │ ├── __init__.py
│ │ └── user_service.py
│ └── main.py # 入口
├── tests/
│ ├── __init__.py
│ └── test_users.py
├── pyproject.toml # 项目配置(类比 package.json)
├── requirements.txt # 依赖清单(旧式,仍常见)
├── .env
├── .gitignore
└── README.md
5.2 __init__.py ↔ package.json exports
__init__.py 表示当前目录是一个包(package),类似 Node.js 中目录下有 package.json 或 index.js 来标识这是一个模块入口。Python 3.3+ 支持隐式命名空间包(可以没有 __init__.py),但习惯上还是保留它,尤其是在有初始化逻辑时。
6. 异步编程
6.1 核心概念对照
| Python | JavaScript |
|---|---|
async def |
async function |
await |
await |
asyncio.run(main()) |
main().catch(console.error) |
asyncio.gather(*tasks) |
Promise.all(tasks) |
asyncio.create_task() |
直接 fn() 返回 Promise |
asyncio.sleep(1) |
setTimeout + Promise |
| 协程(coroutine) | Promise |
| 事件循环(event loop) | 事件循环(libuv) |
6.2 代码对比
python
# ---------- Python ---------- # ---------- JavaScript ----------
import asyncio #
#
async def fetch_user(id: int): # async function fetchUser(id) {
await asyncio.sleep(1) # await new Promise(r => setTimeout(r, 1000));
return {"id": id, "name": "A"} # return { id, name: "A" };
# }
async def main(): # async function main() {
# 并发执行 #
users = await asyncio.gather( # const users = await Promise.all([
fetch_user(1), # fetchUser(1),
fetch_user(2), # fetchUser(2),
) # ]);
print(users) # console.log(users);
# }
asyncio.run(main()) # main();
6.3 关键差异
| 差异点 | Python | JavaScript |
|---|---|---|
| 协程启动方式 | await 调用前不会自动执行 |
Promise 创建即开始执行,await 只是等待结果 |
| 顶层 await | asyncio.run() 包裹 |
Node/Deno 原生支持顶层 await |
| 并发模型 | 单线程 + 协程(真正只有一个线程在跑) | 单线程 + 事件循环(相同) |
| CPU 密集型任务 | 需用 multiprocessing 或线程池 |
需用 Worker Threads |
| Web 框架 async 支持 | FastAPI / aiohttp / Sanic(成熟) | Express 本身不原生 async,Koa 是 async 优先 |
7. 构建与部署
7.1 打包 vs 非打包
Node.js 项目通常会打包(Webpack/Vite/esbuild)再部署,Python 项目一般不打包------直接部署源码 + 依赖。
| Node.js | Python |
|---|---|
npm run build → dist/ |
无需构建,直接部署源码 |
| Webpack / Vite / esbuild | 无打包工具(或用 Cython/Nuitka 编译) |
.js/.ts → .min.js 压缩打包 |
.py 直接运行 |
7.2 依赖管理(生产环境)
bash
# Node.js
npm ci --production # 严格按 lock 文件安装,只装 dependencies
# Python
pip install -r requirements.txt # 安装所有依赖
# 或用 pip-tools 生成精确锁定的 requirements.txt
pip-compile pyproject.toml # 生成 requirements.txt(含所有传递依赖的精确版本)
pip install -r requirements.txt # 按锁定版本安装
7.3 常用部署方式
| 方式 | Node.js | Python |
|---|---|---|
| 直接运行 | node server.js |
python app.py |
| 进程守护 | PM2 | systemd / supervisor |
| 反向代理 + WSGI/ASGI | nginx → node | nginx → gunicorn/uvicorn → app |
| 容器化 | Docker | Docker |
| Serverless | AWS Lambda / Vercel | AWS Lambda / Google Cloud Functions |
类比总结
从 Node.js 切到 Python,记住这几点就够了:
- 缩进就是大括号 ------ Python 用缩进定义代码块,忘记
{}吧 - venv ≈ node_modules + 独立的 node 副本 ------ 每个项目隔离
pip install -r requirements.txt≈npm install------ 安装依赖pyproject.toml≈package.json------ 项目配置(现代方式)def定义函数,class定义类 ------ 和 JS 一样,但语法略有不同- Python 自带电池 ------ 标准库极其丰富,遇到需求先查标准库
- 类型注解是可选但强烈推荐的 ------ 配合 Pydantic 让 Python 有远超 TS 的运行时安全
- 不打包,直接部署源码 ------ 告别 Webpack/Vite
uv pip install xxx更快更现代 ------ 类比pnpm add xxx
思维总结
这种学习方式是给大家希望快速上手的时候使用的,当你需要成为某个领域的专家的时候,还是希望在上手后依旧能够抱着谦虚的心态,多研究多学习,厚实基础。
类比学习法只是为了让大家可以快速上手,快速得到反馈,更容易坚持。否则就以程序员而言,这么多的语言,多学几门,到底需要多少时间,何况工作中未必需要门门语言精通,我们只需要精通自己工作常用的,从而去类比学习其他语言