免费获取学习方案
ARTICLE DETAIL

资讯详情

深耕编程基础知识与建站技术分享的一线实战洞察。

Python基础语法下:条件判断、循环、函数与文件读写实战指南

Python基础语法下:条件判断、循环、函数与文件读写实战指南 很多刚开始学 Python 的同学都有一种感觉变量、数据类型、运算符这些内容很好懂看一遍就会但等到自己写一个稍完整的小程序时却总觉得无从下手。会出现“一行行代码都能看懂合在一起不知道它们在干什么”的尴尬。这其实很正常。如果把 Python 基础语法拆成上下两部分上篇解决的是“怎么说单词、怎么造简单句”而下篇才是真正进入“写段落、写文章”的阶段。下篇的核心不是认识更多语法点而是掌握程序的三种基本结构、代码组织方式以及出错后怎么定位问题。这篇文章会围绕 Python 基础语法中最核心的几条主线展开条件判断、循环、复合数据类型的常用操作、函数、模块导入、异常处理以及文件读写基础。每个部分都会从“为什么需要”讲起再给可直接运行的代码示例最后补充新手容易踩的坑。配套代码都建议自己在本地跑一遍只看不练的效果会差很多。建议先确认你已经完成 Python 环境的安装和基础运行方式命令行、脚本文件再开始阅读本文。如果还没有环境可以回头补一下本课程前面的内容下载 Python 3.x、安装并能在命令行执行python --version输出版本号。1. 这篇文章真正要解决的问题很多人对“基础语法”有误解以为基础就是“变量怎么定义、数字怎么加减”学完这些就可以开始写爬虫、写游戏、做数据分析。实际上真正决定你能否写程序的关键在于你有没有建立起“流程控制”和“代码组织”的思维。先看一个常见的新手场景。你写了一个简单的猜数字程序运行后却发现输入数字后程序不给出任何反应或者条件判断怎么都不成立。你反复检查发现代码里写的是if 用户输入 目标数字而正确的写法是把换成。这类问题几乎每个初学者都遇到过原因不是语法本身难而是脑子里还没有“比较”和“赋值”这两个概念的清晰边界。学完本文你应该能解决以下几个问题怎么让程序根据不同的条件走不同的分支而不是一路顺序执行到底。怎么让一段代码重复执行指定次数或者执行到某个条件满足为止。怎么把函数、列表、字典这些基础元素组合起来写出可读、可复用的小工具。程序运行报错时怎么读懂信息并做出最基本的排查。换句话说这篇文章帮助你从“能看懂 Python 代码”过渡到“能写出一段有逻辑的 Python 代码”。2. 条件判断让程序学会“选择”2.1 为什么需要条件判断计算机程序本质上是在执行指令序列。如果只是从上到下一条条执行程序能做的事情非常有限。真实场景里程序需要根据输入、状态、时间等条件做出不同反应。比如如果用户输入的年龄大于等于 18提示“已成年”。如果文件存在则读取否则创建它。如果订单金额超过 100 元则包邮否则收取运费。这些“如果……否则……”的逻辑就是编程语言中的条件判断。在 Python 中最基础的条件判断关键字是if、elif、else。2.2 if / elif / else 的基本写法最简单的条件判断只有一个分支age 17 if age 18: print(你已成年) else: print(你还未成年)这段代码的逻辑是先判断age 18是否为真如果为真执行print(你已成年)如果为假执行else分支中的内容。这里有两点非常基础但容易出错的规则条件表达式后面要加冒号:不能省略。条件表达式下面的代码必须缩进。Python 用缩进表示代码块同一层缩进的代码属于同一个分支。一般建议使用 4 个空格作为一个缩进层级不要混用 Tab 和空格。elif用于处理多分支情况。例如score 85 if score 90: print(优秀) elif score 80: print(良好) elif score 60: print(及格) else: print(不及格)执行顺序是从上往下依次判断score 90不成立继续检查score 80成立则输出“良好”后面的elif和else都不会再执行。注意只要有一个分支成立整个if语句就结束了。这跟多个独立的if语句是有区别的。2.3 比较运算与逻辑运算条件判断里的条件通常由比较运算和逻辑运算组成。Python 中常用的比较运算符包括运算符含义示例相等a b!不相等a ! b大于a b小于a b大于等于a b小于等于a b比较运算的结果是布尔值True或False。if后面的条件本质上就是一个布尔值。多个条件组合时用逻辑运算符and、or、notage 25 is_student True if age 18 and is_student: print(成年人且为学生)and表示两者同时成立or表示至少一个成立not表示取反。2.4 条件判断最容易被忽略的问题新手最常犯的错误是把赋值当成比较来用。在 Python 中if a 10这种写法会直接报语法错误因为 Python 不允许在条件表达式里直接赋值这是 Python 3.8 之前的规定3.8 之后有海象运算符:但初学阶段不建议使用。另一个值得注意的点是空字符串、空列表、0、None等值在布尔判断中会被当作False。例如name if name: print(名字是, name) else: print(名字为空)输出的是“名字为空”。这个特性在写业务逻辑时非常方便但刚接触时容易误以为只有False才是“假”。记住Python 有一套隐式布尔转换规则普通对象一般默认为True而0、None、空的序列和集合为False。3. 循环让代码重复执行3.1 while 循环先判断再执行while循环的执行逻辑非常简单只要条件为真就不断执行循环体里的代码。count 1 while count 5: print(当前计数, count) count 1这段代码会依次输出1到5。count 1的作用是让count每次循环增加 1。如果漏掉这一步条件count 5永远为真程序就会一直循环下去变成死循环。实际开发中while循环常用于“不确定需要循环多少次”的场景比如一直读取用户输入直到用户输入某个特定值才停止。while True: user_input input(请输入内容输入 q 退出) if user_input q: print(已退出) break print(你输入的是, user_input)break表示强制退出当前整个循环不管条件是否仍然为真。这里先不展开下面会讲到。3.2 for 循环更 Pythonic 的遍历方式for循环在 Python 中使用频率比while高得多。它适合遍历一个可迭代对象例如列表、元组、字符串、字典、range对象等。fruits [apple, banana, cherry] for fruit in fruits: print(fruit)这段代码会依次把fruits里的元素赋值给变量fruit然后执行循环体。如果需要执行固定次数常配合range()使用for i in range(3): print(第, i 1, 次循环)range(3)生成的是0、1、2三个整数不包含3。这是很多新手的理解难点range(n)是“从 0 到 n-1”而不是“从 1 到 n”。range还支持指定起始值和步长for i in range(2, 10, 2): print(i)输出结果是2、4、6、8。语法是range(起始值, 结束值, 步长)结束值同样不包含在内。3.3 break 与 continue控制循环的执行节奏break的作用是提前结束整个循环continue的作用是跳过当前这一轮循环进入下一轮。for i in range(1, 10): if i 5: break print(i)输出结果只有1、2、3、4当i等于 5 时循环整体退出。for i in range(1, 6): if i 3: continue print(i)输出结果是1、2、4、5当i等于 3 时只是跳过了本轮后续循环继续执行。3.4 循环里的 else 子句Python 有一个其他语言不常见的特性for循环和while循环后面可以跟else子句。这个else在循环正常结束时执行如果循环是被break中断的则不执行。for i in range(5): if i 3: break print(i) else: print(循环正常结束)上述代码因为在中途break所以不会输出“循环正常结束”。如果把break去掉最后会输出“循环正常结束”。这个特性可以用来查找逻辑在循环里找某个元素如果找到了就break如果整个循环都结束还没找到就进入else分支做处理。4. 复合数据类型列表、元组、字典的进阶操作如果上篇已经介绍了变量的定义那么下篇就需要重点掌握列表、元组、字典这些复合类型的常用操作。它们是 Python 程序里最常打交道的数据容器。4.1 列表的增删改查列表用方括号表示可以存放多种类型的元素并且是有序的。students [张三, 李四, 王五] # 访问元素 print(students[0]) # 张三 # 追加元素 students.append(赵六) print(students) # 修改元素 students[1] 李四改 print(students) # 删除元素 students.remove(张三) print(students)初学者一开始不需要把所有列表方法背下来但append、remove、索引访问、切片这几类操作要能立刻写出来。它们几乎出现在所有真实程序中。列表切片是很实用的能力。比如取前两个元素、取后两个元素、反序nums [0, 1, 2, 3, 4, 5] print(nums[0:3]) # [0, 1, 2] print(nums[-2:]) # [4, 5] print(nums[::-1]) # [5, 4, 3, 2, 1, 0]切片的基本语法是列表[起始位置:结束位置:步长]结束位置同样不包含在内。[::-1]通过负步长实现倒序非常常用。4.2 元组不可变的列表元组用圆括号表示和列表最大的区别在于元组创建后不可修改。point (3, 5) print(point[0]) # 3 # point[0] 10 # 这行代码会报错元组不支持修改元组适合表示结构固定、不应该变化的数据比如坐标、颜色 RGB 值、配置参数等。后面学函数时函数返回多个值其实返回的就是一个元组。4.3 字典键值对存储字典用花括号表示是一种键值对结构适合根据某个键快速查找对应的值。user { name: 张三, age: 20, city: 北京 } print(user[name]) user[age] 21 print(user.get(age)) print(user.get(email, 未填写))需要注意的是访问字典中不存在的键如果用user[email]会直接报KeyError而使用user.get(email)不会报错会返回None。get还可以指定默认值例如user.get(email, 未填写)返回“未填写”。在实际编程中优先使用get来避免不必要的报错。遍历字典也有几种常见方式for key in user: print(key) for value in user.values(): print(value) for key, value in user.items(): print(key, value)三个场景分别对应“只要键”“只要值”“键和值都要”。4.4 列表推导式简洁地生成列表列表推导式是 Python 特色语法一句话就能完成“遍历 条件过滤 生成新列表”的组合操作。普通写法squares [] for i in range(1, 6): squares.append(i * i) print(squares)列表推导式写法squares [i * i for i in range(1, 6)] print(squares)输出结果都是[1, 4, 9, 16, 25]。列表中还可以加if条件even_squares [i * i for i in range(1, 11) if i % 2 0] print(even_squares)这个例子筛选出 1 到 10 之间的偶数计算平方后放入列表。第一次接触列表推导式时可能会觉得“看不懂”但多写几次就会觉得它比普通循环更直观。建议先掌握普通写法再用推导式简化。5. 函数把代码组织成可复用的模块5.1 为什么要写函数如果一段逻辑要在多个地方使用最笨的办法是复制粘贴。但这样代码会变得非常冗余而且修改需求时要到处改。函数的作用就是把一段逻辑封装起来给它一个名字通过参数接收外部数据通过返回值输出结果。学函数之前写的代码是线性流程从上到下执行。学函数之后写代码的方式会变成“定义一组工具然后在主流程里调用它们”。这是一个很重要的思维方式转变。5.2 定义和调用函数def add(a, b): result a b return result sum_value add(3, 5) print(sum_value) # 8def是定义函数的关键字add是函数名括号里是参数列表return后面是返回值。如果没有return函数会返回None。参数在调用时必须按顺序传入这就是“位置参数”print(add(10, 20)) # 305.3 默认参数与关键字参数定义函数时可以给某些参数设置默认值def greet(name, greeting你好): return greeting , name print(greet(张三)) print(greet(张三, 早上好))调用时如果没传greeting就使用默认值“你好”。默认参数必须放在非默认参数后面否则会报语法错误。关键字参数是指在调用时通过参数名来指定print(greet(greeting晚上好, name李四))使用关键字参数时参数顺序可以打乱这增加了可读性和灵活性。5.4 返回值与多返回值函数不仅可以返回一个值还能返回多个值。Python 内部会把多个返回值打包成一个元组def get_min_max(nums): return min(nums), max(nums) result get_min_max([3, 1, 4, 1, 5]) print(result) # (1, 5) min_value, max_value result print(min_value, max_value)这种写法在同时需要多个计算结果时非常方便。5.5 变量作用域局部变量与全局变量在函数内部定义的变量是局部变量只能在函数内部访问。在函数外部定义的变量是全局变量。x 10 # 全局变量 def change_x(): x 20 # 这是在函数内部新建的局部变量不会影响全局变量 print(函数内部 x , x) change_x() print(函数外部 x , x)输出结果分别是 20 和 10。如果想在函数内部修改全局变量需要用global关键字声明但一个简单原则是尽量少在函数内部修改全局变量而是通过参数传入、返回值传出的方式完成数据交换。这样函数之间的耦合更低代码更容易调试。6. 模块与导入复用已有代码6.1 import 的基本用法Python 拥有非常丰富的标准库和第三方库写程序时不需要什么都自己写。通过import可以把其他模块里的代码引入当前文件使用。import math print(math.sqrt(16)) # 4.0也可以只导入模块里的某个函数from math import sqrt print(sqrt(25)) # 5.0两者区别在于import math导入整个模块使用时要写成math.sqrtfrom math import sqrt直接把sqrt导入到当前命名空间直接用sqrt即可。如果导入多个模块中同名函数后者容易产生命名冲突需要留意。6.2 自定义模块自己也可以写一个.py文件作为模块然后在另一个文件里导入。假设当前目录有两个文件# 文件路径my_utils.py def triple(x): return x * 3# 文件路径main.py import my_utils print(my_utils.triple(4)) # 12只要main.py和my_utils.py在同一个目录下import my_utils就能成功。6.3 ifname main 的作用在 Python 文件里经常能看到这样的写法def main(): print(这是主程序) if __name__ __main__: main()这个写法的意义是当当前文件被直接运行时__name__变量的值是__main__所以会执行main()但当你把这个文件当作模块导入到其他文件时__name__的值是模块名因此main()不会执行不会产生副作用。这在实际项目中很有价值既可以用脚本方式直接运行某个文件测试功能又可以在其他文件中安全导入它而不会一导入就自动执行一段流程。7. 异常处理让程序在出错时不至于崩溃7.1 程序为什么会报错新手写代码时最常见的挫败感来自一堆还看不懂的报错信息。但换个角度想报错其实是 Python 在提醒你出了问题。只要程序还在运行就有机会处理如果程序直接崩溃退出了那就真的什么都做不了。Python 的异常体系很丰富常见的几种有异常类型常见触发原因SyntaxError语法错误例如漏了冒号、括号不匹配NameError使用了未定义的变量TypeError类型不匹配例如字符串和整数直接相加ValueError值不合法例如把非数字字符串转换为整数KeyError访问字典中不存在的键IndexError列表索引越界FileNotFoundError尝试打开不存在的文件7.2 try / except 的基本结构可以用try / except捕获异常并在捕获到之后执行一段处理逻辑。try: num int(input(请输入一个整数)) print(你输入的是, num) except ValueError: print(输入格式不正确无法转换为整数)这段代码的逻辑是尝试执行try块中的代码如果出现ValueError类型的异常就跳到except块执行而不是让程序崩溃。except后面如果不写异常类型会捕获所有异常try: result 10 / 0 except: print(发生了异常)但这种写法不推荐因为会掩盖具体错误信息让调试变得困难。更好的做法是捕获具体异常或者在捕获时把异常信息打印出来try: result 10 / 0 except ZeroDivisionError as e: print(除零错误, e)as e会把异常对象赋值给变量e打印时能看到更具体的描述。7.3 else 与 finallytry语句还可以配合else和finally使用。else在try块没有发生异常时执行finally无论是否发生异常都会执行。try: num int(input(请输入一个整数)) except ValueError: print(输入格式不正确) else: print(转换成功输入的数字是, num) finally: print(无论如何这行都会执行)finally最常见的用途是释放资源、关闭文件或网络连接。文件操作中with语句通常能简化这部分工作但理解finally的执行时机仍然很重要。7.4 异常处理的使用边界不要为了“不让程序报错”而随便包一层try / except。一个好的原则是能前置判断的情况尽量前置判断不要依赖异常来处理正常逻辑。比如判断文件是否存在可以用os.path.exists也可以通过捕获FileNotFoundError来判断。两者各有适用场景后者的优势在于判断和操作之间没有时间窗口相对更可靠。异常处理的重点不是“消灭报错”而是“在报错发生时让程序有合理的退路”。8. 文件读写让数据保存下来程序运行时的变量都保存在内存里程序结束就没了。如果希望数据能持久保存最基本的办法是写入文件。8.1 写入文件with open(output.txt, w, encodingutf-8) as f: f.write(第一行内容\n) f.write(第二行内容\n)这里的w表示写入模式。如果文件不存在会创建如果文件已存在会清空原内容后重新写入。如果不想清空原内容可以使用a模式即追加模式。with语句的作用是“上下文管理器”它会在代码块结束时自动关闭文件不需要手动调用close()。这是 Python 官方推荐的做法不仅代码简洁还能避免因为某些异常导致文件句柄未关闭的问题。8.2 读取文件with open(output.txt, r, encodingutf-8) as f: content f.read() print(content)如果文件不大read()直接读取全部内容是最简单的。如果文件很大可以逐行读取with open(output.txt, r, encodingutf-8) as f: for line in f: print(line.strip())strip()会去掉字符串两端的空白字符和换行符避免打印时出现多余的空行。8.3 文件读写的运行验证建议新手实际运行上面的两个示例先写入再读取观察输出结果是否与预期一致。常见报错是FileNotFoundError原因通常是文件路径不对或者当前工作目录不是文件所在的目录。排查时可以先打印一下当前目录import os print(os.getcwd())9. 完整综合示例把语法点串起来单独看每个语法点都容易理解但合在一起时思路容易乱。下面设计一个小程序把条件判断、循环、列表、字典、函数、文件读写都串起来。需求读取当前目录下的students.txt文件每一行是一组“姓名 分数”数据统计每位学生的等级并把结果写入result.txt。def get_grade(score): if score 90: return 优秀 elif score 80: return 良好 elif score 60: return 及格 else: return 不及格 def process_students(input_file, output_file): result_lines [] with open(input_file, r, encodingutf-8) as f: for line in f: line line.strip() if not line: continue parts line.split() name parts[0] score int(parts[1]) grade get_grade(score) result_lines.append(f{name} {score} {grade}) with open(output_file, w, encodingutf-8) as f: for line in result_lines: f.write(line \n) print(处理完成结果已写入, output_file) if __name__ __main__: process_students(students.txt, result.txt)先创建students.txt张三 85 李四 72 王五 45 赵六 93运行程序之后打开result.txt预期输出张三 85 良好 李四 72 及格 王五 45 不及格 赵六 93 优秀这个示例用到的方法包括函数定义与调用、if / elif / else条件判断、for循环遍历文件行、split()分割字符串、int()类型转换、文件读写、strip()去除空白。代码不长但覆盖了 Python 基础语法的大部分核心内容。建议自己敲一遍不要直接复制完就关掉尝试改动一些逻辑比如增加“平均分计算”看看程序表现。10. 常见问题与排查思路新手在练习 Python 基础语法时遇到的报错翻来覆去就那么几种。下表整理了高频问题、可能原因、排查方式和解决方案。问题现象可能原因排查方式解决方案运行报SyntaxError: expected :条件或循环语句末尾漏写冒号检查if、elif、else、for、while、def后面有没有冒号在对应语句末尾补上冒号运行报IndentationError缩进不一致或混用 Tab 与空格查看报错行附近的缩进统一使用 4 个空格编辑器开启“显示空白字符”报NameError: name xxx is not defined变量名写错或变量还没定义就使用检查变量拼写看变量是否在之前的代码中赋值过修正变量名或在调用前先赋值条件判断结果和预期相反把赋值写成比较的逻辑混淆仔细检查条件表达式中的运算符赋值用比较用循环一直不结束缺少终止条件或忘记让循环变量递增检查while循环体的末尾是否更新了控制变量添加更新语句比如count 1list index out of range访问列表不存在的索引打印列表长度确认索引范围使用len()获取长度或检查遍历逻辑文件读取报FileNotFoundError文件路径不对或当前工作目录不符打印当前目录os.getcwd()确认文件是否存在调整文件路径或把文件放到正确位置多个if都会执行用了多个if而不是elif查看代码是if还是elif多分支判断用elif串起来如果报错信息看不懂最直接的办法是搜索报错文本比如把错误类型ValueError和报错那一行的代码一起搜索。Python 报错信息通常已经包含关键线索先读最后一行再往前找栈信息基本能定位到具体是哪一行触发了问题。11. 最佳实践与工程建议11.1 命名规范变量名、函数名推荐使用小写字母加下划线例如user_name、get_grade。这符合 Python 社区广泛采用的PEP 8风格。常量习惯上使用全大写例如MAX_RETRY 3。不要在命名上用拼音或随意缩写养成一眼能看懂的习惯。11.2 代码风格与可读性使用 4 个空格缩进。每行代码不超过 79 个字符这是 PEP 8 的推荐值当然团队规范可以微调。运算符两边加空格逗号后面加空格。函数之间用两个空行分隔。给复杂逻辑写注释但注释不是把代码翻译成中文而是说明“这段代码为什么这么写”。11.3 函数设计原则尽量让一个函数只做一件事。如果一个函数有几十行里面有输入、计算、打印、文件写入等好几块逻辑就应该考虑拆分。函数命名要能直接表达它的用途如calculate_average比process_data更清晰。11.4 异常处理的时机在程序入口处捕获异常在底层库中尽量不要吞掉异常。也就是说如果在写一个工具函数遇到异常时可以选择抛出或返回默认值但要明确文档说明。不要在每个函数里都写try / except包住所有代码那会让真正的问题被掩盖。11.5 文件读写安全优先使用with语句打开文件保证文件最终被关闭。设置字符编码为utf-8避免中文内容在不同系统上出现乱码。写入重要文件前可以先备份避免意外覆盖原内容。11.6 从“跑通”到“会写”的关键一步很多人看完基础语法后靠复制示例程序运行一次就觉得自己掌握了这其实只完成了 30%。建议练习方式先理解示例代码逐行注释它做了什么。关掉原文凭记忆自己写一遍。修改需求例如把“打印所有偶数”改成“打印所有能被 3 整除的数”。刻意制造错误观察报错信息再修复。这一步如果能坚持做完你对 Python 基础语法的掌握程度会比只看教程提高一个量级。12. 总结与后续学习方向Python 基础语法下的内容主要覆盖了条件判断、循环、复合数据类型常用操作、函数、模块导入、异常处理和文件读写。这些知识拼在一起才构成了“能实现一个小功能”的最低能力集。判断学得怎么样不是看你能背出多少语法规则而是看你能否独立写出类似前面综合示例那样的小程序并在报错后自己定位和修复问题。学完这些之后紧接着的几个推荐方向是面向对象编程理解类与对象写出更复杂、更易扩展的程序结构。常用标准库os、sys、json、datetime、collections等。数据处理基础列表与字典嵌套的实际应用比如把数据组织成结构化格式。小型项目练习写一个命令行通讯录、一个猜数字游戏、一个简单的文件整理脚本。基础语法不需要追求“背得多”而是需要“用得顺”。把这些常用操作变成条件反射后面学面向对象、学爬虫、学数据分析时才不会把大量精力耗费在“这个语法是什么意思”上。如果本文对你有帮助建议收藏起来下次写代码时遇到类似的报错或遗忘点可以回来翻一翻。
返回列表