Python初学者常犯的错误汇总,建议收藏

大家好,我是花姐。

这篇文章想写很久了。为啥?就因为我每天后台、评论区、群聊......总能看到不少刚入门Python的小伙伴,犯了跟我当年一模一样的错。 有的错误吧,说大不大,说小不小,浪费的时间是真心多,一不小心还会让人误以为"自己不适合学编程",结果就被劝退了------太可惜了🙃。

所以这篇文章,我想聊点实在的,从一个学了多年Python的老程序员视角,说说Python初学者常犯的错误,我也踩过,我懂那种懵逼感。


一、变量名乱起,调试想哭😭

你有没有写过这样的代码:

python 复制代码
list = [1, 2, 3]
print(list)

看起来没毛病对吧?运行也能输出。

然后你继续写:

python 复制代码
list.append(4)
print(sum(list))

还是OK的!你会想:嘿,真香!

可问题来了。

你在某个函数里,想用 list() 把元组转成列表:

python 复制代码
nums = list((4, 5, 6))

突然就炸了------TypeError: 'list' object is not callable

为啥?因为你把Python内置函数 list() 给"顶掉"了!等你再写 list() 的时候,它不是函数了,是个你自己定义的变量!Python傻不拉几地就报错了。

这个问题其实很典型,新手常常把内置的关键词当变量名用(什么liststridsum,甚至还有input)------调试的时候,那叫一个酸爽。

聪明的你一定会想到办法的,比如我现在起名字有洁癖,恨不得加后缀加前缀,就为了避开这种内置名😂

💡建议:起变量名别偷懒,用有意义又"避坑"的,比如 my_listuser_input,或者前缀 data_tmp_ 都可以。


二、缩进不一致,一脸懵逼

Python的语法设计真的很干净,但也很"严格"。缩进错误,新手基本上都中招过。

python 复制代码
def say_hi():
    print("Hi")
      print("Hello")

有些编辑器看不出来问题,还能运行一行,然后就报错了。最恶心的是空格和Tab混用------眼睛根本看不出来!

我以前就是因为一个文件里混用了Tab和空格,debug到凌晨两点,差点怀疑人生。

所以一定要设置编辑器默认用空格缩进(4个空格就够),别碰Tab!


三、==和is傻傻分不清

你可能在想:"不都是比较吗?我看教程说都能用啊。"

然后你写:

python 复制代码
a = [1, 2, 3]
b = [1, 2, 3]
print(a == b)  # True
print(a is b)  # False

为啥一个True一个False?

原因很简单:== 比的是"值"是否相等,is 比的是"是不是同一个对象"。

这就像你有两个一模一样的杯子,但一个在你家,一个在我家。你说它们长得一样 ------对,那是==;你说它们是同一个杯子 ------错,那是is

别死记硬背,理解了你就会用了。


四、函数参数默认值是坑,真的坑🕳️

这个是我最想说的。新手99%都会在这里翻车:

python 复制代码
def add_item(item, my_list=[]):
    my_list.append(item)
    return my_list

第一次调用:

python 复制代码
add_item("a")  # ['a']

再来一次?

python 复制代码
add_item("b")  # ['a', 'b']

???怎么上次的"a"还在?

这是因为默认参数是函数定义时就创建 的,my_list=[]这个列表是同一个!每次调用都在往它上面加。不是你以为的"每次都新建一个"。

所以正确写法是:

python 复制代码
def add_item(item, my_list=None):
    if my_list is None:
        my_list = []
    my_list.append(item)
    return my_list

你现在应该懂了吧?🎉聪明的你肯定记住了这个"传参黑洞"。


五、数据类型一换就懵,尤其是None

很多时候,我们对 None 这个东西理解太简单了。

python 复制代码
x = None
if x == False:
    print("Nope")

它不会打印任何东西,因为 None 不是 False。你得写:

python 复制代码
if x is None:
    print("Yep")

别图省事用 ==,用 is 判断 None 才是"Pythonic"。

还有一个例子,大家常写:

python 复制代码
if len(my_list) > 0:
    do_something()

其实可以简写成:

python 复制代码
if my_list:
    do_something()

因为空列表会被当作False,非空则True。这种写法看着就干净、舒服、pythonic。


六、while写成死循环,CPU嗷嗷叫💀

你写个while循环,一不留神忘记加break或者条件永远为真,程序就挂在那儿了。

python 复制代码
while True:
    x = input("输入exit退出:")
    if x == "exit":
        break

这还好,有条件退出。可有时候你写:

python 复制代码
while some_flag:
    # do something

结果 some_flag 永远没变,CPU热得都能煎蛋。

我的建议是,调试阶段你就用print()打点,别嫌麻烦,甚至可以加个计数器,每10次强制break一次,别等到系统都卡死。


七、复制列表翻车,一改全变!

你可能觉得复制列表超简单:

python 复制代码
a = [1, 2, 3]
b = a
b.append(4)
print(a)  # [1, 2, 3, 4]?

然后你一脸懵:"我改的是b啊,a怎么也变了?"

因为你不是复制,而是"赋值了引用"。a和b其实是指向同一个对象

聪明的你一定会想到------要复制得深一点。

最简单的复制方式其实是:

python 复制代码
a = [1, 2, 3]
b = a[:]

或者用 list.copy()

python 复制代码
b = a.copy()

更狠一点,如果是嵌套列表,要用:

python 复制代码
import copy
b = copy.deepcopy(a)

尤其在处理 DataFrame、嵌套结构、传参数的时候,这个坑非常深!


八、文件没关,资源泄露...

我当年也写过这样的代码:

python 复制代码
f = open("data.txt", "r")
data = f.read()
# 然后忘了 close()

Python 不主动提醒你,结果就是文件资源没释放,有些系统里甚至会报 too many open files,开多了系统直接罢工!

聪明的你会想到------with

python 复制代码
with open("data.txt", "r") as f:
    data = f.read()

这个结构叫上下文管理器,你只要缩进写好,它自动给你关掉文件,干净利落不出错。

而且不仅文件,数据库连接、网络连接、锁......都推荐这么写。


九、for循环里修改列表,玩火🔥

你想遍历一个列表,然后删掉里面的某些元素:

python 复制代码
nums = [1, 2, 3, 4, 5]
for n in nums:
    if n % 2 == 0:
        nums.remove(n)

你以为删的是2和4,其实结果是 [1, 3, 5]......有时候还少删一个。

为什么?因为你在遍历的同时改变了原列表,指针跳着跳着就错位了。

解决方法有很多:

  1. 遍历副本删原件:
python 复制代码
for n in nums[:]:
    if n % 2 == 0:
        nums.remove(n)
  1. 用列表推导:
python 复制代码
nums = [n for n in nums if n % 2 != 0]

更优雅也不容易出错。


十、逻辑判断顺序错,全局炸裂🤯

有个经典的判断写法:

python 复制代码
if user['name'] == "花姐":

但万一 user = None 呢?程序就炸了:TypeError: 'NoneType' object is not subscriptable

你想加个保护,于是这样写:

python 复制代码
if user is not None and user['name'] == "花姐":

挺好。但是如果你写反了:

python 复制代码
if user['name'] == "花姐" and user is not None:  # ❌

那还是会爆炸。因为Python会先执行左边的 user['name'],这时候user就是None,炸了。

💡所以:逻辑判断的顺序非常重要!要让"更不容易报错"的条件写在前头。


十一、搞不懂 range 和 list 的区别,一顿乱用🌀

我以前写循环也懵过,写个:

python 复制代码
for i in range(1, 5):
    print(i)

然后读到数据,发现为啥只有1、2、3、4......5去哪儿了?

这玩意儿是左闭右开区间,range(1, 5)只包含1~4,5不包括。

更坑的是:

python 复制代码
x = range(5)
print(x[0])  # 0
print(x)     # range(0, 5)

你以为它是个列表,其实它不是!是一个惰性对象,打印出来啥也看不到。

所以你要真想拿它当列表用:

python 复制代码
list(range(5))  # [0, 1, 2, 3, 4]

别忘了加个 list()


十二、import 自己的脚本,循环引用卡死!

这个比较隐蔽,有些人会写两个文件:

bash 复制代码
main.py
utils.py

然后你在 main.py 里:

python 复制代码
import utils

但在 utils.py 里又写了:

python 复制代码
from main import something

这时候你就死循环了,import的时候互相依赖,Python会报 ImportError: cannot import name ...,或者直接卡住。

建议你项目结构里不要写循环依赖,实在要用就抽公共模块出来。


十三、浮点数精度问题,谁用谁尴尬😓

你可能以为:

python 复制代码
0.1 + 0.2 == 0.3  # True

但其实:

python 复制代码
>>> 0.1 + 0.2
0.30000000000000004

浮点数的世界里,精度永远不准。这不是Python的问题,是计算机底层的问题。

所以你要比精度,用:

python 复制代码
abs(0.1 + 0.2 - 0.3) < 1e-8  # True

别用 == 比浮点,永远是坑。


十四、用了全局变量,以为能改,结果根本没变

你写了个函数,想改全局变量:

python 复制代码
x = 10

def change():
    x = x + 1  # 报错:UnboundLocalError

为啥?因为你在函数里赋值 x = x + 1,Python以为你定义了一个局部变量,但又没初始化。

你得显式告诉Python:我要改全局变量!

python 复制代码
x = 10

def change():
    global x
    x = x + 1

但说句实话,全局变量真心不推荐多用。用类、用参数传递,才是靠谱的代码结构。


十五、逻辑表达式没加括号,结果跑偏

这个坑我小时候写C语言就踩过,没想到Python里又踩了一回。你看这个判断:

python 复制代码
if a > 0 and b < 10 or c == 1:

你可能以为意思是:"a>0 且 b<10,或者 c==1"

但其实这个表达式是这样解析的:

css 复制代码
(a > 0 and b < 10) or (c == 1)

还好对。但你再看这个:

python 复制代码
if a > 0 and b < 10 or c:

你就迷糊了。c 是啥?是 True 吗?是非0就算True?

所以聪明的你一定能想到:这种情况最简单的方法就是------用括号包起来!

python 复制代码
if (a > 0 and b < 10) or c == 1:

这才是你想表达的意思。逻辑表达式别偷懒,多写括号,代码可读性才是王道


十六、try-except 滥用,调试地狱😈

很多人觉得 try-except 是"万能胶",啥错都包住:

python 复制代码
try:
    risky_func()
except:
    pass

这段代码看着舒服吧?但你连哪里错了、为什么错了、错没错都不知道,就直接忽略了。

而且 except: 会捕获所有异常,包括你根本没意识到的问题,比如拼写错误、逻辑错、甚至 KeyboardInterrupt。

聪明点,要指定捕获的异常类型

python 复制代码
try:
    risky_func()
except ValueError as e:
    print("输入值有问题:", e)

别偷懒写万能 except,哪天出了事你找不到锅在哪。


十七、datetime 转字符串,写乱了🌪️

你写过这种时间格式转换吗?

python 复制代码
from datetime import datetime

now = datetime.now()
print(now.strftime("%Y-%m-%d %H:%M:%S"))

不错对吧?

但是你要把字符串再转回来就开始头大了:

python 复制代码
s = "2025-06-10 18:30:00"
dt = datetime.strptime(s, "%Y/%m/%d %H:%M:%S")  # 报错

为啥?你写错格式了!%Y/%m/%d 你原来明明是 -,结果一改就炸。

还有一个更坑的:你用 pandas 写时间序列,忘记转成 datetime 类型:

python 复制代码
df["date"] = "2023-01-01"
df["date"].dt.year  # 报错:Can only use .dt accessor with datetimelike values

记得加一句:

python 复制代码
df["date"] = pd.to_datetime(df["date"])

时间格式相关的坑超级多,建议你写个自己的时间处理函数库封装好,少掉坑。


十八、Boolean 判断写复杂了,自己都看不懂🤪

你有没有写过这种鬼代码:

python 复制代码
if flag == True:
    do_something()

这不是多此一举嘛,直接:

python 复制代码
if flag:

更干净。而更迷惑的是:

python 复制代码
if not flag == True:

这是啥......你到底是想判断 flag != True 还是 not flag

写代码不怕啰嗦,就怕你自己两天后回来看不懂。所以布尔判断就两个建议:

  • 要不就写 if flag:
  • 要不就明确写 if flag is True:if flag is False:

别折腾那些绕来绕去的判等逻辑。


十九、用 lambda 当万能钥匙,写着写着炸了🔑

Lambda 表达式的确好用,但新手很容易过度使用:

python 复制代码
add = lambda x, y: x + y
print(add(1, 2))

挺好用。但你再来个复杂的:

python 复制代码
funcs = [lambda x: x + i for i in range(5)]
print([f(10) for f in funcs])  # 全是14?

为啥?因为 lambda 捕获的是 变量 i 的引用 ,不是当前值。等函数执行的时候,i 早就变成4了。

解决方法?用默认参数绑定当前值:

python 复制代码
funcs = [lambda x, i=i: x + i for i in range(5)]

这才是你想要的 [10,11,12,13,14]

lambda 很香,但也是典型的"写着简单,调试地狱"选手。能写 def 就别省这几行。


二十、input() 永远都是字符串,别再直接拿来加法了

你可能写过这样的代码:

python 复制代码
a = input("请输入一个数字:")
b = input("再输入一个数字:")
print("总和是:", a + b)

你高高兴兴输入了 2 和 3,然后得到:

复制代码
总和是: 23

你人都傻了😂。Python 是不会自动帮你转类型的,input() 的返回值就是个 str

想做数学运算?老老实实加上类型转换:

python 复制代码
a = int(input("请输入一个数字:"))
b = int(input("再输入一个数字:"))
print("总和是:", a + b)

更保险点,加个异常捕获,不然你输入个"hello"也会直接炸掉。


二十一、路径写死了,换台电脑直接崩😤

你写的爬虫、读 Excel,可能这样写路径:

python 复制代码
df = pd.read_excel("C:\\Users\\你的用户名\\Desktop\\数据.xlsx")

在你电脑上没问题。

换别人的电脑?路径没这个人名,直接爆炸。

聪明点,写成动态路径:

python 复制代码
import os
path = os.path.join(os.getcwd(), "数据.xlsx")
df = pd.read_excel(path)

或者用 Pathlib,更高级写法:

python 复制代码
from pathlib import Path
file = Path.cwd() / "数据.xlsx"

我自己之前搞分享代码,每次被同事骂"你这路径写得太不通用了",后来我就改了 😂


花姐叨叨两句

说实话,学Python最容易卡的,真的不是那些语法问题,而是你以为你写对了,其实根本跑偏了的逻辑

错是怎么来的?写多了自然就懂了。 但如果能早点知道一些"坑在哪",你就不会一头撞进去------或者,至少能少撞几次。

这篇文章我已经尽量帮你把我见过最多的新手错误都整理出来了,当然远远不止这些。

我们下篇见~

相关推荐
Python大数据分析@6 分钟前
Origin、MATLAB、Python 用于科研作图,哪个最好?
开发语言·python·matlab
蓝倾6 分钟前
京东批量获取商品SKU操作指南
前端·后端·api
编程零零七34 分钟前
Python巩固训练——第一天练习题
开发语言·python·python基础·python学习·python练习题
Zonda要好好学习1 小时前
Python入门Day4
java·网络·python
开心就好20251 小时前
WebView远程调试全景指南:实战对比主流工具优劣与适配场景
后端
用户21411832636021 小时前
AI 一键搞定!中医药科普短视频制作全流程
后端
SimonKing1 小时前
告别传统读写!RandomAccessFile让你的Java程序快人一步
java·后端·程序员
小龙在山东2 小时前
Python 包管理工具 uv
windows·python·uv
weixin_307779132 小时前
批量OCR的GitHub项目
python·github·ocr
孤狼warrior3 小时前
灰色预测模型
人工智能·python·算法·数学建模