代码语言

知识点思维导图

29 个知识节点

Python(04) - 数据类型与变量

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

  • 绘制“Python(04) - 数据类型与变量 / 变量:没有 let/const,直接赋值”的关键对象与数据流,解释“没有分号(加了也不报错,但不符合习惯,不要加)。 -> 命名习惯是 snake_case(下划线),不是 JS 的 camelCase。 -> 没有 const。Python 没有真正的常量机制,约定俗成用全大写表示"别改我":MAX_SIZE = 100。这只是约定,语法上还是能改。 -> Python 是动态类型,这点和 JS 一样:一个变量可以先存数字再存字符串(虽然不建议)。”,并用源码位置、日志或 Trace 标注证据。
  • 为“Python(04) - 数据类型与变量 / 数字:int 和 float 是两种类型”设计正常与异常输入,验证“/ 永远得到 float:6 / 2 在 Python 里是 3.0 不是 3。”,输出首个偏差位置与回归测试结果。
  • 实现“Python(04) - 数据类型与变量 / 字符串 str:没有反引号,用 f-string”的最小代码或配置,检验“求长度是 len(s) 不是 s.length。 -> 不会自动转类型:"年龄" + 18 在 JS 里得到 "年龄18",在 Python 里直接报错(TypeError)。”,输出命令、结果与 Diff,并说明不适用边界。

你已经会 JS 的 number / string / Array / Object / Map / Set。这篇就把 Python 的 int / float / str / list / dict / tuple / set 一一对上号,重点不是"它们长什么样",而是哪里和 JS 不一样、哪里会让你踩坑

一、先建立一个总锚点

把 Python 的内置类型对照 JS,大致是这张表:

JavaScript Python 一句话区别
number(不分整数小数) int / float Python 把整数和小数分成两种类型
string str 单引号双引号都行,没有反引号模板字符串(用 f-string 代替)
booleantrue/false boolTrue/False 首字母大写
null / undefined None 只有一个空值,没有 undefined
Array[] list[] 长得一样,方法名差很多
Object{},键只能字符串) dict{},键可以是任意不可变值) 字面量像,但 dict 是更纯粹的"字典"
Map dict Python 没有单独的 Map,dict 一肩挑
Set set{} 概念一样
—(JS 无) tuple() 不可变的 list,JS 里没有直接对应

下面逐个讲透,并且每讲一个就立刻划清和 JS 的边界,防止你拿 JS 心智模型硬套。


二、变量:没有 let/const,直接赋值

Python 声明变量就是一个等号,不需要 let/const/var,也不写类型

// JavaScript(对照)
let count = 10;
let name = "Tom";
let isActive = true;

边界(哪里不一样):

  1. 没有分号(加了也不报错,但不符合习惯,不要加)。
  2. 命名习惯是 snake_case(下划线),不是 JS 的 camelCaseis_active 而不是 isActive
  3. 没有 const。Python 没有真正的常量机制,约定俗成用全大写表示"别改我":MAX_SIZE = 100。这只是约定,语法上还是能改。
  4. Python 是动态类型,这点和 JS 一样:一个变量可以先存数字再存字符串(虽然不建议)。

注意:Python 也有"类型注解"(count: int = 10),但它和 TS 不同——运行时完全不检查、不报错,纯粹给人和工具看。后面讲 Pydantic / FastAPI 时会再展开(详见后续 Pydantic 篇)。


三、数字:int 和 float 是两种类型

JS 只有一个 number,Python 拆成了 int(整数)和 float(小数):

// JavaScript(对照)
let c = 10 / 3;          // 3.333...
let d = Math.floor(10 / 3); // 3,JS 没有整除运算符
let f = 2 ** 10;         // 1024,** 这个和 Python 一样

边界:

  • / 永远得到 float6 / 2 在 Python 里是 3.0 不是 3。想要整数结果用 //
  • int 没有大小上限:JS 超过 Number.MAX_SAFE_INTEGER 会失真,Python 的 int 可以无限大(2 ** 1000 直接算出精确值),这点比 JS 强。
  • float 一样有浮点误差:0.1 + 0.2 == 0.3 在 Python 里同样是 False,和 JS 一个毛病。

四、字符串 str:没有反引号,用 f-string

// JavaScript(对照)
let msg = `Hello, ${name}, you are ${age}`;  // 反引号 + ${}
let msg2 = "Hello, " + name;

对照表:

JavaScript Python 说明
`Hello ${name}` f"Hello {name}" 模板字符串,Python 用 f"..." 而非反引号
str.length len(s) Python 没有 .length 属性,统一用 len() 函数
str.toUpperCase() s.upper() 转大写
str.toLowerCase() s.lower() 转小写
str.includes("x") "x" in s 是否包含,用 in 关键字更地道
str.split(",") s.split(",") 切分,一样
str.trim() s.strip() 去首尾空白
str.replace("a","b") s.replace("a", "b") 替换
arr.join("-") "-".join(arr) 方向反了:Python 是「分隔符.join(列表)」

边界(最容易踩的两个坑):

  1. 求长度是 len(s) 不是 s.length。这是新手最高频的错。listdict 也都用 len()
  2. + 不会自动转类型"年龄" + 18 在 JS 里得到 "年龄18",在 Python 里直接报错TypeError)。必须显式转:"年龄" + str(18),或者干脆用 f-string。

五、list:长得像 Array,方法名不一样

list 就是 Python 的"数组",字面量也是 []

// JavaScript(对照)
let fruits = ["apple", "banana", "cherry"];
fruits.push("orange");
let first = fruits[0];
let last = fruits[fruits.length - 1];  // JS 要手动算
let count = fruits.length;

方法对照:

JavaScript Python 说明
arr.push(x) list.append(x) 末尾追加单个
arr.pop() list.pop() 弹出末尾,一样
arr.length len(arr) 长度用函数
arr.includes(x) x in arr 是否包含
arr.indexOf(x) arr.index(x) 找下标(找不到 Python 会报错,JS 返回 -1)
arr.map(f) [f(x) for x in arr] 列表推导式,后面单独讲
arr.filter(f) [x for x in arr if f(x)] 列表推导式
arr.slice(1, 3) arr[1:3] 切片语法,Python 用方括号+冒号

边界——切片(slicing)是 Python 的招牌特性,JS 没有等价语法:

这个切片语法后面看 NumPy / Pandas 会反复用到,先混个眼熟。


六、dict:JS 的 Object 和 Map 合二为一

dict 是 Python 的字典,字面量也是 {},但它更像 JS 的 Map(纯键值存储),而不是带方法的 Object:

// JavaScript(对照)
let user = { name: "Tom", age: 18 };
let name = user["name"];          // 或 user.name
let age = user.age;
user.email = "t@x.com";
let exists = "name" in user;      // 或 user.hasOwnProperty("name")

对照表:

JavaScript(Object) Python(dict) 说明
obj.key / obj["key"] d["key"] Python 没有点号访问,只能用方括号
obj.key(不存在得 undefined) d["key"](不存在报错 关键差异!用 d.get("key") 才返回 None
obj["key"] = v d["key"] = v 赋值一样
delete obj.key del d["key"] 删除
Object.keys(obj) d.keys() 所有键
Object.values(obj) d.values() 所有值
Object.entries(obj) d.items() 键值对,常用于遍历
"key" in obj "key" in d 判断键存在

边界(两个核心差异):

  1. 没有点号访问:JS 习惯 user.name,Python 只能 user["name"]。(点号在 Python 里是访问对象的属性/方法,是另一回事。)
  2. 取不存在的键会抛 KeyError,不是返回 undefined。所以读取拿不准的键,养成用 .get(key, 默认值) 的习惯。

遍历 dict 的地道写法:


七、tuple:JS 里没有的"不可变 list"

tuple(元组)用圆括号 (),可以理解成一旦创建就不能改的 list。JS 里没有直接对应物。

// JavaScript(对照):JS 没有 tuple,通常用数组模拟,但数组能改
function getSize() {
  return [1920, 1080];
}
const [width, height] = getSize();  // 解构和 Python 几乎一样

边界:

  • 为什么要有 tuple? 表达"这组数据是固定的,别改"(坐标、RGB 颜色、数据库一行记录)。不可变 = 更安全、能当 dict 的键、性能略好。
  • 单元素 tuple 有个坑(5) 不是 tuple,是数字 5 加了层括号;必须写 (5,)逗号才是元组的灵魂

八、set:去重集合

set{},存不重复的元素,概念和 JS 的 Set 一样:

// JavaScript(对照)
let tags = new Set(["python", "web", "python"]);
tags.add("ai");
let has = tags.has("web");
let unique = [...new Set([1, 1, 2, 3, 3])];  // 去重技巧

边界(一个语法陷阱):

  • 空集合不能写 {}{} 是空 dict,不是空 set。空集合必须写 set()。这是 Python 用 {} 同时表示两种类型留下的历史坑。

九、可变 vs 不可变(理解这个能少踩一半坑)

这是 Python 类型体系里最该建立的一个直觉。把内置类型分两类:

不可变(创建后不能改) 可变(能原地修改)
int / float / bool list
str dict
tuple set
None

这点其实和 JS 高度相似——JS 里 string/number 是值类型(不可变),object/array 是引用类型(可变)。同样的坑也存在:

// JavaScript(同样的引用陷阱)
let a = [1, 2, 3];
let b = a;          // 引用赋值
b.push(4);
console.log(a);     // [1, 2, 3, 4],a 也变了
let c = [...a];     // 浅拷贝

一句话:list/dict/set 赋值是传引用,要复制得显式 copy。这和 JS 的对象/数组完全一致,你已经懂这个直觉。


十、类型转换与查看类型

// JavaScript(对照)
let n = parseInt("123");   // 或 Number("123")
let s = String(123);
let t = typeof n;          // "number"

边界:

  • 假值(falsy)规则和 JS 类似但不完全相同:Python 里 0""None[](空列表)、{}(空字典)、set()(空集合)都是假值。JS 里空数组 [] 和空对象 {} 反而是真值——这是个容易反向踩的坑。
  • 判断类型用 isinstance(x, int)type(x) == int 更地道(能正确处理继承关系)。

十一、总结

  • 先建立一个总锚点:| JavaScript | Python | 一句话区别 |
  • 变量:没有 let/const,直接赋值:没有分号(加了也不报错,但不符合习惯,不要加)。 -> 命名习惯是 snake_case(下划线),不是 JS 的 camelCase。 -> 没有 const。Python 没有真正的常量机制,约定俗成用全大写表示"别改我":MAX_SIZE = 100。这只是约定,语法上还是能改。 -> Python 是动态类型,这点和 JS 一样:一个变量可以先存数字再存字符串(虽然不建议)。
  • 数字:int 和 float 是两种类型:/ 永远得到 float:6 / 2 在 Python 里是 3.0 不是 3。
  • 字符串 str:没有反引号,用 f-string:求长度是 len(s) 不是 s.length。 -> 不会自动转类型:"年龄" + 18 在 JS 里得到 "年龄18",在 Python 里直接报错(TypeError)。
  • list:长得像 Array,方法名不一样:| arr.includes(x) | x in arr | 是否包含 |
  • dict:JS 的 Object 和 Map 合二为一:没有点号访问:JS 习惯 user.name,Python 只能 user["name"]。 -> 取不存在的键会抛 KeyError,不是返回 undefined。

学完自测

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

1在“数据类型与变量”中,需要同时满足“先建立一个总锚点”与“变量:没有 let/const,直接赋值”。给定正文约束“把 Python 的内置类型对照 JS,大致是这张表。”,哪些判断保持了原有处理机制?多选
2“数据类型与变量”出现偏差:“在“数据类型与变量 / 数字:int 和 float 是两种类型”中,即使不满足“6 / 2 在 Python 里是 3.0 不是 3”,结果与副作用仍会保持不变。”已成为实际行为。围绕“数字:int 和 float 是两种类型”与“字符串 str:没有反引号,用 f-string”,哪些判断能定位被改变的职责或边界?多选
3评审“数据类型与变量”方案时,验收条件包含“这个切片语法后面看 NumPy / Pandas 会反复用到,先混个眼熟。”。关于“list:长得像 Array,方法名不一样”与“dict:JS 的 Object 和 Map 合二为一”的哪些决策符合正文机制?多选