经常收到私信问我:想学Python但不知道从哪开始,收藏了一堆教程却连第一步都没迈出去。有人卡在安装上,装完了打开一个黑窗口就懵了;有人装是装好了,但不知道用什么写代码;还有人跟着网上的例子敲了两行就报错,一报错就关掉再也没打开过。
这篇东西就是干这个事的。我准备把零基础入门Python最绕不开的三件事一次讲透:环境搭建、核心语法、常用数据类型。不懂编程的能跟着一步步照做,以前摸过一点但没系统学的,也能借这篇把底子补齐。时长大概一个下午,敲完这些代码,你就具备自己写小脚本解决实际问题的能力了。
先说清楚我的立场:我不是卖课的,也不是写文档的,就是常年用Python干活、也带过不少新人入门的从业者。下面讲的全是我在实际中反复验证过、觉得零基础最该先掌握的东西,废话不多,直接开工。
1. 环境搭建:别急着装一堆东西,先想清楚你要的是什么
1.1 为什么环境这一步能劝退一半的人
Python本质上是一个解释器程序,你说“装Python”,其实就是把解释器装到电脑上,让它能读懂你写的.py文件。很多新手一上来就搜“Python安装教程”,装完了发现还有Anaconda、VS Code、PyCharm、Jupyter、pip、虚拟环境这些词,瞬间头大。
我的建议很简单:零基础第一周只需要三样东西——Python解释器、一个趁手的编辑器、一个能跑命令的终端。其他的什么Anaconda、Jupyter、虚拟环境,你以后用到再说,现在装了反而徒增困惑。
还有一个常见误区:有人觉得“用网页在线编辑器不就行了吗,何必装环境”。在线编辑器能帮你跑通语法,但你会错过一个最关键的体验——在自己电脑上直接运行脚本的感觉。而且后续你要装第三方库、读写文件、调用摄像头,这些必须本地环境才能玩。所以第一步老老实实装本地环境。
1.2 Python版本怎么选:别追新,选稳定
去python.org下载的时候,你会看到3.x的小版本很多,比如3.10、3.11、3.12、3.13。新手不用纠结太久,我的建议是选当前时间点最新的稳定版,但别选刚刚发布的大版本(比如刚出3.13的那阵子我就不太推荐,生态兼容还没跟上)。稳妥的做法是选3.10到3.12之间的小版本。
不要装2.x版本,Python 2已经彻底停止维护了,网上那些老教程动不动就出现print "hello"这种写法,就是2.x的语法,你照着写肯定是错的。
下载的时候注意看是64位还是32位。现在绝大多数电脑都是64位,选Windows installer (64-bit)就行。macOS用户直接下载macOS 64-bit universal2 installer,一路下一步也能装好。
1.3 Windows和macOS的安装实操
Windows用户的关键一步:安装向导第一屏下面有个Add Python to PATH的复选框,一定要勾上。这个勾选决定你之后在终端里能不能直接输入python命令,无数人栽在这里,装完发现“python不是内部或外部命令”,十有八九就是没勾这个。
装完怎么验证?打开终端(Windows按Win + R,输入cmd回车;macOS打开“终端”App),输入:
python --version看到类似Python 3.11.x的输出,就说明装好了。再顺手验证一下包管理工具:
pip --versionmacOS用户如果输入python没反应,试试python3。这算是macOS一个惹人烦的小毛病,系统自带的Python 2残留和一些软链接问题导致命令不一致,没什么大碍,后面我会在常见问题里细说。
如果下载官网太慢,可以用国内的开源镜像站下载安装包,速度和稳定性都有保障。这类镜像站是正规的开源软件分发渠道,安心用就行。
1.4 编辑器选型:VS Code还是PyCharm
装上解释器之后,你还需要一个写代码的地方。纯文本编辑器(记事本)当然也能写,但没有任何辅助提示,一个括号写错就要折腾半天,不推荐。
我见过太多新手在“选哪个编辑器”这个选择题上反复横跳,一说VS Code好用就装VS Code,一看别人用PyCharm又说PyCharm专业,搞了两天还在装软件。编辑器只是工具,核心是让你赶紧开始写代码。
| 对比项 | VS Code | PyCharm 社区版 |
|---|---|---|
| 上手难度 | 较低,轻量 | 中等,功能全 |
| 安装体积 | 小,启动快 | 较大,启动稍慢 |
| 调试功能 | 够用 | 更强 |
| 智能提示 | 安装Python插件后很好 | 开箱即用 |
| 适合谁 | 推荐零基础首选 | 喜欢集成环境的人 |
我个人推荐零基础从VS Code开始。原因就一个:它轻,你不用在一堆窗口和配置里迷路,装一个官方Python插件就能写。等以后你开始做完整项目了,再换PyCharm或者继续用VS Code都行,这不影响你学Python本身。
VS Code装完之后,在扩展商店搜Python,选微软官方发布那个(发行方是Microsoft),装完重启一下。写代码的时候它会自动帮你做语法高亮和代码提示,体验差很远。
1.5 终端里跑起来:你的第一个Python程序
先别急着写文件,我教你用Python自带的交互模式直接体验一下。在终端输入:
python你会看到提示符变成>>>,这就是进入了Python交互环境,也叫REPL(Read-Eval-Print Loop)。在这里输入的每一行代码,回车就立刻执行。就像你跟Python解释器在聊天,你说一句它回一句。
输入下面这行,回车:
print("Hello, Python")看到输出Hello, Python,恭喜,你的环境真的通了。这个时刻值得停一下,因为很多人就是从这里开始,从一个“看教程的人”变成一个“动手写程序的人”。
按Ctrl + Z(Windows)或Ctrl + D(macOS)退出交互模式。然后我们再走一遍正规流程:新建一个hello.py文件,在VS Code里打开,写入:
print("Hello, Python")保存后,在VS Code的终端里运行:
python hello.py看到同样输出。这就完整跑通了“写文件—运行文件”的流程,以后写脚本都是这么干。
1.6 虚拟环境:现在还不用深究,但得知道这个名字
你可能会在教程里频繁看到“虚拟环境”“venv”“conda”这些词。简单打个比方:Python自带的包就像你家客厅里的公共物品,所有项目都能用;而虚拟环境就是在家里隔出一个个独立房间,每个房间有自己的一套工具,互相不干扰。
为什么要这么搞?因为以后你跑不同项目,可能需要不同版本的第三方库(比如A项目用pandas 1.x,B项目用pandas 2.x),全装到全局就会打架。用虚拟环境就能各玩各的。
零基础阶段,你先知道有这回事即可。等你真的要装pytorch、yolov8这类重量级框架时,再回来学venv或conda也不迟。这里提它,是为了让你之后看到相关教程不慌——这不是什么高深的东西,就是项目管理的一个机制罢了。
2. Python核心语法:先掌握能让程序跑起来的骨架
2.1 变量和赋值:Python的变量比你想得自由
Python不需要你提前声明变量类型,直接起个名字、用等号赋值就行:
name = "张三" age = 28 height = 1.78 is_student = True这几种写法分别给变量name、age、height、is_student赋了不同类型的值。注意Python是动态类型语言,意思是同一个变量名可以一会儿存数字、一会儿存字符串:
x = 10 x = "现在变成字符串了"这在C语言或Java里是绝对不允许的,但在Python里合法。初学者会觉得这太随意,但实际这是Python舒服的地方——写脚本时不用为了类型声明浪费心力。
但变量命名有规矩,记三条就够了:
- 只能用字母、数字、下划线,且不能以数字开头(
1var是错的,var1是对的); - 不能起名叫
if、for、while、class这些Python关键字; - 习惯上用
小写字母+下划线风格,比如my_name,这叫snake_case。
2.2 基础运算:别小看这里,坑都在细节里
常见的算术运算符:
print(10 + 3) # 13 print(10 - 3) # 7 print(10 * 3) # 30 print(10 / 3) # 3.3333333333333335 print(10 // 3) # 3 print(10 % 3) # 1 print(10 ** 3) # 1000两个容易懵的地方:/是普通除法,结果是浮点数;//是整除,直接去掉小数部分。%是取余数。**是幂运算,表示10的三次方。
比较和逻辑运算:
print(5 > 3) # True print(5 == 3) # False print(5 != 3) # True print(True and False) # False print(True or False) # True print(not True) # False这里特别提醒:判断相等是==两个等号,不是=一个等号。一个等号是赋值,两个等号才是比较,这是新手报错排行榜前三的错误来源。
字符串也能参与一些运算:
print("Hello" + " " + "Python") # 字符串拼接 print("=" * 20) # 字符串重复,输出20个等号2.3 条件判断:让代码知道什么情况下做什么
if语句的写法是:
score = 85 if score >= 90: print("优秀") elif score >= 60: print("及格") else: print("不及格")注意三个细节:
- 条件后面要加冒号
:; - 条件满足后执行的代码,前面要缩进(Tab键或4个空格),Python用缩进而不是大括号来划分代码块,这是Python最鲜明的语法特点;
- 判断顺序是从上往下,
elif的意思是“否则如果”,前面判断为假才检查后面的。
缩进错误是零基础最容易犯的毛病。一会没缩进、一会缩进了多一格,程序就报IndentationError。我的建议是:全篇统一用4个空格,不要让Tab和空格混用。很多编辑器会自动把Tab转成4个空格,你只要别手动去混合就行。
2.4 循环:让重复操作交给机器
最常见的for循环:
for i in range(5): print(i)输出0、1、2、3、4。range(5)生成从0到4的整数序列,注意不包括5,这是新手第一次接触最容易疑惑的点。想要1到5,写成range(1, 6)。
while循环适合不知道具体循环几次的场景:
count = 0 while count < 3: print("还在循环中", count) count += 1count += 1就是count = count + 1的简写。写while循环千万小心:如果忘了让条件改变,程序就会无限循环,窗口一直刷屏。要是遇到这种情况,按Ctrl + C强制中断。
break用于提前跳出循环,continue用于跳过本次剩余代码进入下一次:
for i in range(10): if i == 3: continue # 跳过3 if i == 7: break # 到7直接结束循环 print(i)2.5 函数:把一段逻辑打包成可复用的零件
函数是代码复用的基础。定义一个函数:
def add(a, b): result = a + b return result sum_value = add(3, 5) print(sum_value) # 8def是定义函数的关键字,后面跟函数名、括号里的参数、冒号,函数体要缩进。return用来把计算结果返回给调用方。如果一个函数没有return,它默认返回None。
函数参数还可以有默认值:
def greet(name, greeting="你好"): print(greeting + ", " + name) greet("张三") # 你好, 张三 greet("李四", "晚上好") # 晚上好, 李四零基础阶段,把函数理解成“自己造的快捷指令”就行:把一段逻辑用名字封装起来,需要用的时候喊一声。等你以后学到类、装饰器那些东西,会发现它们的根基都在“函数”这个概念上。
3. 常用数据类型全解析:Python程序的血肉
3.1 先看全景图:Python有哪些内置数据类型
Python常用的数据类型就这些,背下来不费劲:
| 类型 | 名称 | 示例 | 可变性 |
|---|---|---|---|
int | 整数 | 42 | 不可变 |
float | 浮点数 | 3.14 | 不可变 |
str | 字符串 | "hello" | 不可变 |
bool | 布尔值 | True | 不可变 |
NoneType | 空值 | None | 不可变 |
list | 列表 | [1, 2, 3] | 可变 |
tuple | 元组 | (1, 2, 3) | 不可变 |
dict | 字典 | {"name": "张三"} | 可变 |
set | 集合 | {1, 2, 3} | 可变 |
“可变”指的是数据本身能不能被修改:列表可以增删元素,所以可变;字符串一旦创建就改不了,所以不可变。这个概念很重要,后面很多让人费解的问题都源于此。
用内置函数type()可以查看任何数据的类型:
print(type(42)) # <class 'int'> print(type("hello")) # <class 'str'> print(type([1, 2])) # <class 'list'>3.2 数字类型:int和float的日常与精度陷阱
整数和小数是最基础的类型。大部分运算都很直观,但有一个坑几乎人人会遇到——浮点数精度:
print(0.1 + 0.2)你可能以为输出0.3,实际输出的却是0.30000000000000004。这不是Python的bug,而是所有编程语言在二进制里存储十进制小数时都有的精度问题。C语言、Java也一样,只是Python直接给你显示出来了。
解决方式有几个:想比较两个浮点数,别用==,改用“差值小于一个极小值”的办法;做金额计算不想有精度问题,用Decimal模块。零基础阶段知道有这么回事就行,但别在某次运行结果奇怪时慌。
3.3 字符串:你打交道最多的类型
字符串一眼就能认出来:被单引号或双引号包裹的内容。要注意的是,Python里字符串是不可变的,你对字符串做修改操作,实际上都是生成一个新字符串。
常用操作:
s = " hello, Python " print(s.strip()) # 去掉首尾空格: "hello, Python" print(s.upper()) # 大写: " HELLO, PYTHON " print(s.lower()) # 小写: " hello, python " print(s.replace("Python", "Java")) # 替换 print(s.split(",")) # 按逗号拆成列表: [' hello', ' Python '] print(len(s)) # 长度字符串拼接和格式化,零基础阶段掌握三种方式就够:
name = "张三" age = 28 # 方式一:加号拼接 print("我叫" + name + ",今年" + str(age) + "岁") # 方式二:%格式化 print("我叫%s,今年%d岁" % (name, age)) # 方式三:f-string,最推荐 print(f"我叫{name},今年{age}岁")f-string是Python 3.6之后引入的写法,在字符串前加f,用花括号直接嵌入变量,最直观最好用。能少敲代码且不容易错,就该优先选它。强烈建议你现在就开始用f-string,以后写爬虫、做数据分析、写脚本,到处都用得上。
字符串切片是个挺有趣的操作,字符串[start:end],从start取到end之前:
s = "python" print(s[0:2]) # "py" print(s[2:]) # "thon" print(s[-1]) # "n",负索引从末尾数 print(s[::-1]) # "nohtyp",逆序3.4 列表:最常用、最灵活的数据容器
列表用方括号定义,可以存放任意类型的元素,并且同一个列表里可以混装不同类型:
fruits = ["apple", "banana", "cherry"] mixed = [1, "two", 3.0, True]列表的核心操作,这几个必须熟练掌握:
fruits = ["apple", "banana", "cherry"] # 访问元素(索引从0开始) print(fruits[0]) # apple print(fruits[-1]) # cherry,负索引取最后一个 # 修改元素 fruits[1] = "blueberry" # 追加元素 fruits.append("orange") # 插入元素 fruits.insert(1, "pear") # 删除元素 fruits.remove("apple") # 按值删,只删匹配到的第一个 popped = fruits.pop() # 按索引删,不传参数默认删最后一个,并返回它 # 判断是否存在 print("apple" in fruits) # True # 列表长度 print(len(fruits))列表也可以像字符串一样切片:
nums = [0, 1, 2, 3, 4, 5] print(nums[1:3]) # [1, 2] print(nums[::2]) # [0, 2, 4]遍历列表,两种写法:
colors = ["red", "green", "blue"] for color in colors: print(color) for i, color in enumerate(colors): print(i, color)enumerate()同时拿到索引和元素,在写代码时非常实用,比如你想知道“当前处理到第几个元素”的时候。
列表推导式是个能让你看起来“很Pythonic”的语法,零基础可以先会用,不急着深究:
squares = [x ** 2 for x in range(10)] print(squares) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]这行代码等价于:
squares = [] for x in range(10): squares.append(x ** 2)列表推导式看着简洁,但读起来对新手有点门槛。我的建议是:看不懂就先写普通循环,功能完全一样,等以后写多了自然能欣赏它的简洁。
3.5 字典:按名字查值的神器
字典是键值对的集合,用花括号定义:
person = { "name": "张三", "age": 28, "city": "上海" } print(person["name"]) # 张三 print(person.get("age")) # 28字典的核心操作:
# 新增或修改 person["job"] = "工程师" # 键不存在就是新增 person["age"] = 29 # 键已存在就是修改 # 删除 person.pop("city") # 按键删除 del person["city"] # 也可以这样删 # 判断键是否存在 print("name" in person) # True # 遍历 for key in person: print(key, person[key]) for key, value in person.items(): print(key, value)字典用得着了,就会想一个问题:什么时候用person["name"],什么时候用person.get("name")?区别在于:键不存在时,person["name"]会直接报KeyError错误,而person.get("name")返回None,还可以传默认值:
print(person.get("salary", 0)) # 没有salary这个键,返回0我建议:不确定键一定存在的时候,一律用get()。尤其在处理外部数据(比如解析接口返回的JSON)的时候,用get()能省掉很多判断,代码也不会因为某个字段缺失就崩。
3.6 元组和集合:两个容易混淆的兄弟
元组用圆括号定义,和列表很像,但有一个根本区别:元组不可变。
point = (10, 20) print(point[0]) # 10 # point[0] = 5 # 报错,元组不支持修改元组适合存“本就不打算改”的数据,比如坐标、日期、函数返回的多个值。还有些场景从底层上依赖元组的不可变性,比如它可以作为字典的键,列表就不行。
集合用花括号定义,但和字典不同——它只有元素,没有键值对。集合两大特性:去重和集合运算:
nums = [1, 2, 2, 3, 3, 3] unique = set(nums) print(unique) # {1, 2, 3} a = {1, 2, 3} b = {2, 3, 4} print(a & b) # 交集 {2, 3} print(a | b) # 并集 {1, 2, 3, 4} print(a - b) # 差集 {1}注意空集合不能写成{},这会被当成空字典,要写set()。
3.7 可变与不可变、可哈希:理解数据类型深层的钥匙
很多人学到数据类型就停留在“记住每个类型怎么用”,一旦遇到诡异报错就懵了。其实只要理解“可变与不可变”这个底层概念,很多问题都能自己推导出来。
不可变类型的代表:整数、浮点数、字符串、元组。你执行s = s + "a"时,不是修改了原来的字符串,而是创建了一个新字符串,然后让变量名指向它。
可变类型的代表:列表、字典、集合。你执行list.append(1)时,是在原列表上直接修改,不产生新对象。
由此引出一个关键概念——可哈希。简单说,能计算出固定哈希值的对象才能作为字典的键或放进集合。Python规定:不可变类型通常是可哈希的,可变类型不可哈希。所以你会看到:
- 字符串、整数、元组能当字典键;
- 列表、字典不能当字典键,硬用会报
TypeError: unhashable type: 'list'。
为什么不让你用列表当键?因为列表内容能变,键一变,哈希值就变了,字典查值就乱了。这个设计不是故意为难你,而是为了保证数据结构的正确性。
理解这一层,你再回头看“为什么tuple存在,明明list也能存数据”——因为元组的不可变性,让它能在需要“不可篡改”的场景里派上用场。数据类型不是随便定出来的,每个设计都有它的理由。
4. 类型转换与实战延伸:跨过书和代码之间的那条沟
4.1 常用类型转换函数:编织数据的一座桥
Python提供了一组转换函数,用来在类型之间切换:
print(int("42")) # 字符串转整数 42 print(float("3.14")) # 字符串转浮点数 3.14 print(str(123)) # 整数转字符串 "123" print(list("abc")) # 字符串转列表 ['a', 'b', 'c'] print(tuple([1, 2])) # 列表转元组 (1, 2) print(list((1, 2))) # 元组转列表 [1, 2] print(set([1, 1, 2])) # 列表转集合,顺带去重 {1, 2}用的时候要留神几个坑:
int("3.14")会直接报错,字符串里的小数不能直接转整数,得先转成float再转int,即int(float("3.14"));int("42")能成功,但int("42abc")会报错,字符串里必须确实是数字;- 布尔值的转换最容易让人懵:
bool("False")的结果是True,因为在Python里,非空字符串都是True。想按字符串内容判断真假,写成"False" == "False",别指望bool()帮你干活。
4.2 判断类型:type和isinstance怎么选
拿type()能看出类型,但做判断时更推荐isinstance():
print(type("abc") == str) # True print(isinstance("abc", str)) # Trueisinstance()的优势在于它能识别继承关系,并且支持同时判断多个类型:
print(isinstance(5, (int, float))) # True在写函数的时候,经常需要对传入参数做类型检查或容错,这两个函数就是你的工具。但有个口诀送给你:判断类型用isinstance,调试查看用type。
4.3 延展:其他常见场景里的数据类型对照
学Python的数据类型时,很多人会有一个疑问:是不是所有语言的数据类型都一样?还真不是完全一样。我用几个你可能会接触到的场景做个对比,帮你建立坐标系。
C语言要声明变量时指定类型,比如int a = 1; float b = 1.5;,并且int的存储字节数在不同平台上可能有差异,涉及数据在内存里如何存放的问题。而Python是动态类型,你不用声明类型,解释器自己判断,代价是运行时开销更大、底层细节被封装掉了。
Java的int是32位有符号整数,有固定范围,超出就溢出。Python的int则无限制,能存任意大的整数,对大数运算非常友好。这就是为什么处理超大整数时,Python写起来天然省心。
再看现在常见的开发场景:后端服务用Java或Go时,接口返回值要做强类型定义,用OpenFeign这类组件通过泛型指定返回的封装类型;而Python +pandas做数据分析时,你拿到一列数据往往要调用astype()做数据类型转换,比如把字符串类型的数字列转成数值类型才能做聚合运算。
我提这些不是为了让你现在就去学,而是想说:“数据类型”这个概念在编程里是共通的,跨语言迁移时你只需要记差异,不需要重新学。Python把这部分的体验做得最轻松,这也是很多人拿它当第一门语言的原因。
4.4 实际里最常见的组合用法
数据类型不是孤立的,真实代码里往往是几类数据嵌套使用。最常见的组合是列表套字典,比如下面这份学生信息:
students = [ {"name": "张三", "score": 85}, {"name": "李四", "score": 92}, {"name": "王五", "score": 76}, ] for student in students: print(f"{student['name']} 的分数是 {student['score']}")这种结构在处理数据时极常见——接口返回的JSON解析出来,就是字典套列表、列表套字典的形式。你以后做爬虫、调API、处理Excel,本质上都是在跟这种嵌套结构打交道。
还有一种常见操作:把两个列表合成字典。
names = ["张三", "李四"] scores = [85, 92] result = dict(zip(names, scores)) print(result) # {'张三': 85, '李四': 92}zip()把两个列表按位置配对,dict()再把配对结果转成字典。这种思路就是“数据变换”的开始——以后学pandas清洗数据、做特征工程,脑子里装的都是这种“从一种形式变换到另一种形式”的思维。
5. 零基础高频报错与排查实录:踩过的坑你提前避开
5.1 “python不是内部或外部命令”:九成是PATH的问题
这是Windows用户装完Python后最常遇到的第一道坎。原因前面说过,安装时没勾选Add Python to PATH,系统不知道去哪找python。
解决办法有两个:
- 卸载重装一遍,这次勾上那个复选框;
- 不想重装的话,手动把Python安装路径和它的
Scripts子目录加入环境变量。右键“此电脑” → 属性 → 高级系统设置 → 环境变量,在Path里新增两条:C:\Users\你的用户名\AppData\Local\Programs\Python\Python311\和同路径下的Scripts目录。
我建议直接用重装的办法,省心。但也要说一句:现在Python新版安装包即使没勾PTH,装完也会问你是否要“修复”环境,新版本引导比老版本友好多了,你没勾的话大概率也会被提醒。
macOS用户遇到python没反应时试python3,这是因为macOS自带Python 3的系统策略问题。但Python官网安装包装完后一般两端都能用,只有系统自带环境才会这样。
5.2 pip安装第三方库很慢甚至失败
零基础学一阵子后,就会遇到“装第三方库”的需求,比如pip install requests。如果下载慢或超时,大概率是默认下载源在国外。解决办法是换成国内镜像,常见的有清华、阿里、豆瓣等,使用方式:
pip install requests -i https://pypi.tuna.tsinghua.edu.cn/simple想一劳永逸,就配置默认镜像源,让pip以后都从国内源下载。
5.3 IndentationError:缩进问题
IndentationError: unexpected indent这个报错的含义是:哪一行的缩进和预期不一致。排查思路很简单——检查报错行附近是不是多敲了空格,或者混用了Tab和空格。
有个办法能让你彻底告别这个错误:在VS Code里,点右下角的状态栏,把缩进方式统一设为“通过空格”,缩进量设为4。这样你按Tab键时,编辑器会物理地插入4个空格,不会出现Tab和空格混用的问题。
5.4 用内置名字当变量名,导致奇怪报错
新手很容易写出这样的代码:
list = [1, 2, 3] dict = {"a": 1}然后下一行再用list()或dict()时,突然报错TypeError: 'list' object is not callable。原因是你把list这个原本指向内置函数的名字,重新赋给了列表,Python解释器自然就用不了内置函数了。
解决办法:别用list、dict、str、int、type这类内置名字当变量名。如果你确实需要一个列表变量,叫my_list或者data都行。
5.5 常见报错速查表
| 报错信息 | 常见原因 | 解决办法 |
|---|---|---|
SyntaxError: invalid syntax | 少写了冒号、括号、引号 | 检查报错行及其上一行的符号闭合 |
NameError: name 'xxx' is not defined | 变量名拼错,或没赋值就用 | 检查变量名是否拼写一致,是否先赋值 |
TypeError: 'int' object is not callable | 变量名覆盖了内置函数,或错误地加括号 | 检查是否有变量叫str、int、list等 |
KeyError: 'xxx' | 字典里没有这个键 | 用.get()替代[],或先检查键是否存在 |
IndexError: list index out of range | 访问列表不存在的索引 | 检查索引是否越界,用len()确认长度 |
ValueError: invalid literal for int() | 用int()转换了非数字字符串 | 确认字符串内容确实是纯数字 |
ModuleNotFoundError: No module named 'xxx' | 第三方库没装 | pip install xxx,并确认用的是同一个Python环境 |
这张表我建议收藏,以后报错了先对照看看,比直接复制错误去搜索引擎都快。当然搜索引擎也行,但学会自查,进步会快得多。
5.6 另一个隐藏坑:pip装到了另一个Python上
最后说一个几乎每个用一段时间Python的人都会踩到的坑。电脑上可能装了多个Python版本(官网版、Microsoft Store版、Anaconda自带的),你执行python和pip时,它们指的可能不是同一个解释器。于是出现“pip装完了,但运行时还是找不到模块”的诡异情况。
排查命令:
python --version pip --version看看两个命令输出里Python的路径是否一致。如果路径不同,说明pip和python来自不同环境。最稳妥的玩法是用python -m pip而不是直接敲pip:
python -m pip install requestspython -m pip的意思是“用当前的python解释器去执行pip模块”,这样装到的包,一定属于当前这个解释器,不会装错地方。从今天起,我建议一律使用python -m pip命令,省很多事。
我带过很多人入门,发现一个规律:卡住的从来不是“知识点太难”,而是“环境问题消耗了太多热情”。一个报错查了半天不敢往下走,兴致就没了。所以我才把这张排查表整理出来——你遇到错误,停止自我怀疑,先对着表查,90%的入门问题都在这张表里。
按我说的把这些代码敲完、跑通,你已经不是“零基础”了,你是“能写一点程序的人”。接下来可以试着给自己写点小工具:批量改文件名的脚本、抓网页标题的爬虫、处理Excel的小工具。写一个成一个,那种成就感比光看教程强百倍。