代码语言

知识点思维导图

29 个知识节点

Python(03) - Python 与 JavaScript 对比

读完后,你应能完成以下任务:

  • 绘制“Python(03) - Python 与 JavaScript 对比 / 核心思路”的关键对象与数据流,解释“和你从 JS 转 Java 不同:Java 是"强类型 + 编译检查",处处和 JS 别扭;”,并用源码位置、日志或 Trace 标注证据。
  • 为“Python(03) - Python 与 JavaScript 对比 / 变量和类型”设计正常与异常输入,验证“True / False / None 首字母大写。 -> int 和 float 是分开的两种类型(JS 只有一个 number)。 -> 没有 undefined,空值只有 None 一个。”,输出首个偏差位置与回归测试结果。
  • 实现“Python(03) - Python 与 JavaScript 对比 / 变量声明”的最小代码或配置,检验“全大写 AGE 只是约定告诉别人"别改我",语言层面照样能改。”,输出命令、结果与 Diff,并说明不适用边界。

你已经会 JS/TS,本篇用一张对照表帮你把 Python 的变量、函数、类型、常用操作一次性对上号。重点不是"记语法",而是划清那些长得像但行为不一样的坑(比如 self 不是 thisis 不是 ===)。

一、核心思路

Python ≈ 动态类型的 JS(像不写类型的 JavaScript),但用缩进代替 {}、用换行代替 ;

和你从 JS 转 Java 不同:Java 是"强类型 + 编译检查",处处和 JS 别扭;而 Python 的类型系统和 JS 几乎一样松(运行时才检查),所以上手比 Java 顺。真正的差异集中在三处:写法(缩进/命名)几个同名不同义的关键字、以及 self 这个最大的陷阱

边界提醒:本篇只讲语法对照,建立"我大概会写了"的直觉。像 async 不受 GIL 影响、装饰器机制、生成器原理这些,留到对应专题篇深入。


二、变量和类型

2.1 变量声明

JavaScript TypeScript Python
let name = "Tom" let name: string = "Tom" name = "Tom"
const AGE = 18 const AGE: number = 18 AGE = 18(约定大写表示常量)

关键差异(边界):

  • 没有 let / const / var,直接 变量名 = 值
  • Python 没有真正的常量。全大写 AGE 只是约定告诉别人"别改我",语言层面照样能改。这点和 JS 的 const(真正只读)不一样,别套用。
  • 行尾不写分号 ;(写了也不报错,但不符合习惯)。
  • 命名习惯是 snake_case(下划线),不是 JS 的 camelCase。这是社区强约定,建议入乡随俗。

2.2 类型提示(Type Hints)≈ TS 的类型注解

Python 默认动态类型,但可选地写类型提示,写法和 TS 几乎一样(都是"变量名在前、类型在后"):

// TypeScript:类型是强制检查的
let count: number = 10;
let userName: string = "Tom";

边界:TS 的类型在编译期会报错;Python 的类型提示运行时完全不检查,写错类型照样跑。它的价值是给 IDE 补全和 mypy 这类静态检查工具用。后面学 FastAPI / Pydantic 时,类型提示会"变成真的"(被框架拿去做校验),到那篇再展开。

2.3 基本类型对照

JS/TS Python 说明
number int 整数
number float 小数(浮点)
string str 字符串
boolean bool 布尔值,True / False 首字母大写
null / undefined None 空值,只有一个 None,首字母大写
Array list 列表
object / Map dict 字典
[a, b](TS 元组类型,但默认可改) tuple 元组(真正不可变
Set set 集合

最容易踩的三个坑:

  1. True / False / None 首字母大写。写成 JS 的 true / null 会直接报 NameError
  2. intfloat 是分开的两种类型(JS 只有一个 number)。10 是 int,10.0 是 float。
  3. 没有 undefined,空值只有 None 一个。
// JavaScript
let isActive = true;
let data = null;

三、函数

3.1 声明格式

JavaScript Python
function add(a, b) { return a + b } def add(a, b): return a + b
箭头函数 (a, b) => a + b lambda a, b: a + b

Python 格式:

3.2 完整例子(并排对照)

// JavaScript
function greet(name) {
    return "Hello, " + name;
}

带类型提示的版本(≈ TS):

3.3 默认参数 & 关键字参数(比 JS 强大)

JS 的默认参数你已经会。Python 额外支持调用时按名字传参,可读性很高:

// JavaScript:默认参数
function createUser(name, age = 18) { ... }
createUser("Tom");           // 只能按位置传

坑:默认参数不要用可变对象(如 def f(items=[]))。因为默认值只在定义时创建一次,多次调用会共享同一个 list,导致诡异 bug。需要时用 def f(items=None): items = items or []。这是 Python 新手的经典陷阱。

3.4 程序入口:没有 main,但有 if name == "main"

Python 没有 Java 那种强制的 main 方法。文件从上到下直接执行。但有个固定写法用来区分"被直接运行"还是"被 import":

类比:有点像 Node 里判断 if (require.main === module)——只在直接运行时跑入口逻辑。


四、列表、字典与常用操作

4.1 列表 list ≈ JS Array

list 就是 JS 的 Array,但方法名变了:

// JavaScript
let arr = [1, 2, 3];
arr.push(4);            // 末尾追加
arr.length;             // 长度
arr[0];                 // 取第一个
arr.includes(2);        // 是否包含
JS Python
arr.push(x) arr.append(x)
arr.length len(arr)
arr[i] arr[i]
arr.includes(x) x in arr
arr.slice(1, 3) arr[1:3](切片语法)
arr[arr.length - 1] arr[-1]负索引取倒数,JS 没有)

亮点:Python 的切片很强。arr[1:3] 取索引 1~2,arr[-1] 取最后一个,arr[::-1] 直接反转。这是 JS 没有的语法糖。

4.2 字典 dict ≈ JS object / Map

// JavaScript
let map = {};
map["age"] = 18;        // 或 map.age = 18
map["age"];             // 取值
delete map["age"];      // 删除
"age" in map;           // 是否有 key
JS Python
obj[key] = value d[key] = value
obj[key] d[key]
obj.key(点语法) ❌ 不支持,只能用 d[key]
obj[key] ?? default d.get(key, default)
delete obj[key] del d[key]
Object.keys(obj) d.keys()

坑:字典取不存在的 key 会抛 KeyError 异常,不像 JS 返回 undefined。不确定 key 在不在时,用 d.get(key)(默认返回 None)或 d.get(key, 默认值)

4.3 列表推导式 ≈ map / filter 的浓缩写法

JS 里 arr.map(...).filter(...) 链式调用,Python 有更紧凑的列表推导式

// JavaScript
let nums = [1, 2, 3, 4];
let doubled = nums.map(n => n * 2);              // 每个翻倍
let evens = nums.filter(n => n % 2 === 0);       // 只留偶数

读法:"结果表达式 for 元素 in 集合 if 条件"。一开始别扭,写几次就顺了,这是 Python 最常用的写法之一。


五、类和对象(最大的坑:self)

5.1 类定义

// TypeScript
class User {
    name: string;
    age: number;

    constructor(name: string, age: number) {
        this.name = name;
        this.age = age;
    }

    greet(): string {
        return `Hello, ${this.name}`;
    }
}
const u = new User("Tom", 18);

关键差异(重点边界):

  1. self 不是 thisthis 是 JS 隐式给的,Python 的 self 必须手动写成方法的第一个参数,并且调用时不用传(解释器自动塞进去)。这是前端转 Python 最高频的报错来源。
  2. 构造方法固定叫 __init__,不是 constructor
  3. 创建对象不用 new,直接 User("Tom", 18)
  4. 访问成员一律 self.xxx,漏写 self. 会被当成局部变量。

为什么 self 要显式写?(WHY) Python 的设计哲学是"显式优于隐式"——方法本质上就是个普通函数,u.greet() 等价于 User.greet(u),那个 u 就是传给 self 的。理解了这一层,self 就不神秘了。

5.2 f-string(模板字符串)

// JavaScript:反引号 + ${}
let msg = `Hello, ${name}, you are ${age}`;

一对一映射,把反引号换成 f"..."、去掉 $ 即可。


六、控制流(和 JS 像,但有几个坑)

6.1 条件判断

JS Python 说明
else if elif 拼写不同
&& || ! and or not 用英文单词,不是符号
=== == Python 没有 ===== 比的是值
a ? b : c b if a else c 三元语序反了,结果在前
// JavaScript 三元
let result = age >= 18 ? "成年" : "未成年";

6.2 循环

坑:Python 没有 ++ / -- 自增运算符。要写 count += 1 / count -= 1


七、相等判断与真值(高频坑)

7.1 == vs is

is 不是 JS 的 === 别被长度迷惑。规则:

  • ==(这是日常默认选择)。
  • is 只用在判断 None:写 if x is None:,这是社区规范(不写 x == None)。
// JavaScript
if (data === null) { ... }

7.2 真值(Truthy / Falsy)

和 JS 类似但更直觉:空列表 []、空字典 {}、空字符串 ""0None 都是假值。


八、模块与包(≈ import / npm)

8.1 导入导出

Python 没有 export——一个文件(模块)里定义的所有东西默认都能被别的文件导入。

// JavaScript
import { add } from './utils';
import axios from 'axios';
JS Python
import { x } from './m' from m import x
import * as m from './m' import m(用 m.x 调用)
export function x 无需导出,定义即可被导入
npm install axios pip install requests
package.json requirements.txt / pyproject.toml
node_modules/ 虚拟环境 venv/(见环境配置篇)

边界:JS 的依赖装在项目本地 node_modules;Python 默认装到全局,所以才需要虚拟环境隔离不同项目(环境篇已讲)。心智上 pipnpmvenv ≈ 项目级隔离。


九、常见语法速查表

功能 JavaScript/TypeScript Python
变量 let x = 1 x = 1
常量 const X = 1 X = 1(仅约定大写)
代码块 { ... } 缩进(4 个空格)
行尾 ; 直接换行
命名 camelCase snake_case
字符串模板 `Hi ${name}` f"Hi {name}"
函数 function f(x) {} def f(x):
箭头函数 (x) => x + 1 lambda x: x + 1
空值 null / undefined None
布尔 true / false True / False
逻辑与或非 && || ! and or not
相等 === ==(判空用 is None
三元 a ? b : c b if a else c
列表追加 arr.push(x) arr.append(x)
长度 arr.length len(arr)
字典取值 obj[k] / obj[k] ?? d d[k] / d.get(k, 默认)
包含判断 arr.includes(x) x in arr
遍历 for (const x of arr) for x in arr:
带索引遍历 arr.entries() enumerate(arr)
自增 i++ i += 1(无 ++
this this self(需显式声明)
构造器 constructor() def __init__(self)
实例化 new User() User()(无 new)
输出 console.log(x) print(x)
注释 // /* */ # """ """

十、总结

  • 核心思路:和你从 JS 转 Java 不同:Java 是"强类型 + 编译检查",处处和 JS 别扭;
  • 变量和类型:True / False / None 首字母大写。 -> int 和 float 是分开的两种类型(JS 只有一个 number)。 -> 没有 undefined,空值只有 None 一个。
  • 函数:因为默认值只在定义时创建一次,多次调用会共享同一个 list,导致诡异 bug。
  • 类和对象(最大的坑:self):self 不是 this。 -> 构造方法固定叫 init,不是 constructor。 -> 创建对象不用 new,直接 User("Tom", 18)。 -> 访问成员一律 self.xxx,漏写 self. 会被当成局部变量。
  • 控制流(和 JS 像,但有几个坑):| && || ! | and or not | 用英文单词,不是符号 |
  • 模块与包(≈ import / npm):边界:JS 的依赖装在项目本地 node_modules;

学完自测

选择所有正确答案;提交后逐项核对判断依据。

1在“Python 与 JavaScript 对比”中,需要同时满足“核心思路”与“变量声明”。给定正文约束“而 Python 的类型系统和 JS 几乎一样松(运行时才检查),所以上手比 Java 顺。”,哪些判断保持了原有处理机制?多选
2“Python 与 JavaScript 对比”出现偏差:“在“Python 与 JavaScript 对比 / 类型提示(Type Hints)≈ TS 的类型注解”中,即使不满足“Python 默认动态类型,但可选地写类型提示,写法和 TS 几乎一样(都是"变量名在前、类型在后")”,结果与副作用仍会保持不变。”已成为实际行为。围绕“类型提示(Type Hints)≈ TS 的类型注解”与“基本类型对照”,哪些判断能定位被改变的职责或边界?多选
3评审“Python 与 JavaScript 对比”方案时,验收条件包含“带类型提示的版本(≈ TS)。”。关于“完整例子(并排对照)”与“默认参数 & 关键字参数(比 JS 强大)”的哪些决策符合正文机制?多选