🧀🧀🧀前端仔如何快速上手python

前端仔快速上手 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 生态有两套主流方案分别是内置的venvanaconda(我习惯性使用anaconda),所以这里先介绍anaconda的安装,个人是不建议直接安装python的,就像作为前端我也不建议直接安装node,而是建议安装nvm之类的版本管理工具。

如果不喜欢使用anaconda的也可以选择使用venv,以下是一些对比内容

anaconda官网下载

直接从官网下载安装,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.jsonindex.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,记住这几点就够了:

  1. 缩进就是大括号 ------ Python 用缩进定义代码块,忘记 {}
  2. venv ≈ node_modules + 独立的 node 副本 ------ 每个项目隔离
  3. pip install -r requirements.txtnpm install ------ 安装依赖
  4. pyproject.tomlpackage.json ------ 项目配置(现代方式)
  5. def 定义函数,class 定义类 ------ 和 JS 一样,但语法略有不同
  6. Python 自带电池 ------ 标准库极其丰富,遇到需求先查标准库
  7. 类型注解是可选但强烈推荐的 ------ 配合 Pydantic 让 Python 有远超 TS 的运行时安全
  8. 不打包,直接部署源码 ------ 告别 Webpack/Vite
  9. uv pip install xxx 更快更现代 ------ 类比 pnpm add xxx

思维总结

这种学习方式是给大家希望快速上手的时候使用的,当你需要成为某个领域的专家的时候,还是希望在上手后依旧能够抱着谦虚的心态,多研究多学习,厚实基础。

类比学习法只是为了让大家可以快速上手,快速得到反馈,更容易坚持。否则就以程序员而言,这么多的语言,多学几门,到底需要多少时间,何况工作中未必需要门门语言精通,我们只需要精通自己工作常用的,从而去类比学习其他语言

相关推荐
阿黎梨梨2 小时前
AI 推理太慢用户要退钱?前端流式输出(Stream)究竟是何方神圣?
前端·vue.js
只一2 小时前
从0到1吃透AI流式输出:Vue3+DeepSeek实战,解锁丝滑对话体验
前端·vue.js
JZC_xiaozhong2 小时前
OA调价审批后,采购调价单如何自动同步到ERP?解决漏录错价难题
大数据·linux·服务器·前端·数据库·数据孤岛解决方案·数据集成与应用集成
卷无止境2 小时前
Flet 完全教程:用纯 Python 构建跨平台应用
前端·python
Cobyte2 小时前
24.Vue Vapor 组件事件 emit 的实现
前端·javascript·vue.js
Flynt2 小时前
TypeScript 5.8 让我少踩了一个大坑,顺手再聊聊 --erasableSyntaxOnly
前端·javascript·typescript
用户2930750976692 小时前
# 从零开始,打造 AI 产品的第一个关键体验——流式输出
前端·vue.js
小杍随笔2 小时前
【 .npmrc 终极配置指南:统一管理 npm/pnpm 缓存与全局目录,告别磁盘混乱】
前端·缓存·npm
默_笙2 小时前
👍 手写一个 MCP 文件读取服务:原来 AI 能"读"我的文件,全靠这个协议
前端·javascript