多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

Python交互式与文件式运行方式:5个实例教你选对场景

Python交互式与文件式运行方式:5个实例教你选对场景 提到 Python 的两种运行方式很多人第一反应是这有什么好讲的不就是python进交互模式、python 某某.py跑脚本嘛。但真到了实际项目里我发现能把这两种方式用对、用好的人其实不多。尤其是初学者在交互式环境里敲了一堆代码关掉窗口全丢了或者写脚本时遇到缩进错误、编码问题折腾半天不知道问题出在哪。这篇文章我就用 5 个实例程序把交互式和文件式这两种运行方式从头到尾拆一遍。每个实例都能在两种方式下运行我会告诉你它们各自的表现差异、适用场景、常见坑点以及我在实际调试中总结出来的一些经验。不管你是刚接触 Python 的纯新手还是已经写了一段时间但始终没搞懂“为什么有时候直接敲代码、有时候要写文件”的老手这篇内容都能帮你把基础打扎实。1. 两种运行方式的核心差异与选型思路1.1 交互式方式Python 解释器的“对话模式”交互式方式也叫 REPLRead-Eval-Print Loop读取-求值-打印-循环。你在终端里输入一行代码解释器立刻执行一行并把结果打印出来。整个过程就像你和 Python 解释器在对话你问一句它答一句。这种方式的本质是“即时反馈”。我经常用它来做三件事验证某个语法是否正确、测试某个函数返回什么结果、快速算一组数据。比如你忘了dict.get(key, default)的默认值参数怎么用直接在交互式里敲一下几秒钟就有答案比翻文档快得多。但交互式有个天然的短板代码不持久。你敲的每一行都会被解释器“消化掉”如果你想回退修改某一行没法像文本编辑器那样直接改只能重新敲一遍。所以交互式适合临时计算、探索性编程、调试小片段不适合写完整的逻辑。1.2 文件式方式把代码变成可复用的“脚本”文件式方式就是把代码写进一个.py文件然后用python 文件名.py一次性执行。这种方式下Python 解释器会从头到尾把文件里的代码全部执行一遍然后退出。文件式的核心价值是“可重复执行”。写好的代码保存下来随时可以再次运行也可以传给其他人用。更重要的是文件里可以写复杂的逻辑定义函数、循环、异常处理、导入模块这些在交互式里很难维护但在文件里可以组织得井井有条。实际项目里几乎所有的正式代码都是以文件式存在的。这也符合软件工程的基本思想代码是可维护的资产而不是一次性输入的命令。1.3 为什么选 5 个实例程序来演示我特意挑了 5 个实例程序而不是随便写两个例子原因很简单这两个运行方式的差异只有放到不同类型的代码里才能体现得淋漓尽致。实例 1 是最简单的输出两者几乎没差别但能帮你确认环境没问题实例 2 涉及变量和类型转换交互式的即时反馈优势在这里很明显实例 3 有条件判断和循环文件式的批量执行优势开始显现实例 4 有函数定义交互式里定义一次就得全部重敲文件式里改一行就行实例 5 是文件读写和异常处理交互式里处理异常时的 traceback 更直观但文件式里才能真正体现“写一遍跑多次”的价值。这 5 个实例从简单到复杂每一个都能在两种方式下运行通过对比你会直观感受到“什么时候该用交互式、什么时候该写文件”。2. 5 个实例程序的设计思路与代码准备2.1 实例 1Hello, Python 入门输出先来个最经典的。这个实例的目的不是展示什么高级语法而是确认你的 Python 环境是好的顺便感受一下两种方式的基本操作流程。print(Hello, Python!) name Python 学习者 print(你好 name)在交互式里你逐行输入每行输入完回车结果立刻显示。在文件式里把这两行存成hello.py然后python hello.py一次性输出两行结果。这个实例本身没有难度但它是后续所有操作的基础。我见过不少新手卡在环境配置上python命令输进去结果打开了 Windows 应用商店或者提示“python 不是内部或外部命令”。这些问题先解决掉再谈交互式和文件式。2.2 实例 2变量与类型转换第二个实例开始接触数据处理。我们做一个“摄氏度转华氏度”的小工具输入摄氏度输出华氏度同时展示整数、浮点数、字符串三种类型的自动转换过程。celsius 25 fahrenheit celsius * 9 / 5 32 print(摄氏度:, celsius, 华氏度:, fahrenheit) # 把字符串转换为浮点数再参与运算 celsius_str 26.5 celsius_float float(celsius_str) fahrenheit_2 celsius_float * 9 / 5 32 print(字符串转换后计算华氏度:, fahrenheit_2)这个例子的重点在于类型转换。celsius是整数celsius * 9 / 5 32的结果是浮点数运算符优先级和隐式类型转换都体现出来了。float(celsius_str)则是显式类型转换把字符串变成浮点数。在交互式里跑这个例子你能清楚地看到每一步计算的结果比如celsius * 9 / 5等于多少、加上 32 之后等于多少。在文件式里你不会看到中间过程只能看到最终的 print 输出。2.3 实例 3条件判断与循环结构第三个实例引入流程控制。我们写一个程序打印 1 到 10并把偶数单独标记出来。for i in range(1, 11): if i % 2 0: print(i, 是偶数) else: print(i, 是奇数)这个例子很简单但它在两种方式下的体验差异非常大。在交互式里你需要在for循环体内注意缩进。敲完第一行for i in range(1, 11):后解释器会显示...提示符等你继续输入缩进的代码块。这时候新手经常犯的一个错误是回车之后忘记缩进结果报IndentationError。在文件式里编辑器会自动帮你维护缩进只要整块代码的缩进保持一致运行就不会出问题。你还能在编辑器里直观地看到代码块的结构比如for下面缩进的代码都属于循环体。2.4 实例 4函数封装与调用第四个实例上升到代码组织层面。我们把“判断偶数”的逻辑封装成一个函数然后多次调用。def is_even(num): 返回 True 如果 num 是偶数否则返回 False return num % 2 0 for i in range(1, 11): if is_even(i): print(f{i} 是偶数) else: print(f{i} 是奇数) print(函数文档说明:, is_even.__doc__)这个实例在交互式里会暴露一个很现实的问题一旦你敲完整个函数定义按了两下回车函数就固定下来了。哪怕你发现return那行有个小错误也得把整个函数重新敲一遍。在文件式里就简单多了改一行保存重新运行完事。这个例子最能说明为什么“正式代码必须写在文件里”——因为代码是要反复改的。2.5 实例 5文件读写与异常处理最后一个实例演示实际项目里最常见的场景读取外部文件处理数据必要时捕获异常。try: with open(data.txt, r, encodingutf-8) as f: content f.read() print(文件内容:) print(content) except FileNotFoundError: print(找不到文件 data.txt请先创建该文件) except UnicodeDecodeError: print(文件编码不是 UTF-8请检查文件编码) finally: print(文件操作尝试结束)在交互式里跑这个例子你能直接看到异常对象是什么样的比如FileNotFoundError的 traceback 会显示在哪个文件哪一行抛出的。这是一种很直观的调试方式。在文件式里跑同样的代码如果你没有data.txt程序会捕获异常并打印提示信息不会因为异常导致程序崩溃。这个区别非常重要交互式里异常会直接打断你当前的操作而文件式里的异常可以被捕获、被处理程序还能继续跑。3. 交互式环境实操指南3.1 进入与退出交互式环境先说说怎么进入交互式环境。Windows、macOS、Linux 的做法基本一样在终端里输入python或python3然后回车。$ python Python 3.11.5 (main, Aug 24 2023, 11:36:53) [GCC 12.2.0] on linux Type help, copyright, credits or license for more information. 看到提示符就说明你已经进入交互式环境了。退出方式有两种一是输入exit()或quit()二是直接按CtrlDLinux/macOS或CtrlZWindows加回车。有个小细节如果你在交互式里输入exit而不是exit()在某些旧版本 Python 里只会显示“Use exit() or Ctrl-Z plus Return to exit”这样的提示并没有真正退出。这是新手经常遇到的问题记住要带括号。3.2 在交互式环境中逐个验证 5 个实例现在我们把 5 个实例在交互式里跑一遍。第一个和第二个很简单直接输入即可 print(Hello, Python!) Hello, Python! name Python 学习者 print(你好 name) 你好Python 学习者 celsius 25 fahrenheit celsius * 9 / 5 32 print(摄氏度:, celsius, 华氏度:, fahrenheit) 摄氏度: 25 华氏度: 77.0第三个实例涉及循环你需要特别注意缩进。完整的输入过程是 for i in range(1, 11): ... if i % 2 0: ... print(i, 是偶数) ... else: ... print(i, 是奇数) ... 1 是奇数 2 是偶数 3 是奇数 4 是偶数 5 是奇数 6 是偶数 7 是奇数 8 是偶数 9 是奇数 10 是偶数注意看每行代码前的...提示符是 Python 自动生成的表示你在续行。循环体内的每一行都要有一个 tab 或 4 个空格作为缩进且缩进数量必须一致。如果你输入完else:后下一行直接回车循环就结束了。第四个实例在交互式里定义函数时我建议你一次性把整个函数体连续输入完中间不要停顿太久免得自己都忘了前面写了什么。如果输错了某个局部变量名可以用CtrlC取消当前输入重新开始。第五个实例涉及文件读取在交互式里运行时的特点是可以看到完整的异常 traceback这在调试时是很有用的信息 try: ... with open(data.txt, r, encodingutf-8) as f: ... content f.read() ... print(文件内容:, content) ... except FileNotFoundError: ... print(找不到文件 data.txt) ... 找不到文件 data.txt3.3 交互式的优势和效率短板交互式最大的好处是反馈快适合探索和验证。比如你在写代码时不确定某个内置函数的用法进交互式试一下几秒钟就有结果不需要创建文件不需要清理临时脚本效率非常高。但它的短板也很致命。首先代码不会自动保存终端一关所有输入全部消失。其次当你输入一个很长的函数定义时任何一个微小的错误都要重来。第三交互式环境里定义的变量会一直保存在内存中你可能会因为变量名冲突导致计算错误。比如你在上面定义了name Python 学习者后面如果忘了这个变量已经存在再拿它做别的用途结果可能完全不是你想要的。所以我的经验是交互式只用来“试”不用来“写”。正式代码永远写在文件里。4. 文件式环境实操指南4.1 创建脚本文件与运行方法文件式运行方式的第一步是创建一个文本文件把代码写进去。文件名以.py结尾比如hello.py、demo.py。可以用任何文本编辑器创建VS Code、Sublime Text、Notepad 都可以甚至 Windows 自带的记事本也能写但我不推荐因为没有语法高亮和自动缩进出错的概率会大很多。写好文件后在终端里进入文件所在目录运行$ python hello.py Hello, Python! 你好Python 学习者如果你的系统同时装了 Python 2 和 Python 3可能需要用python3 hello.py来指定版本。判断方法很简单python --version看一下版本号。4.2 把 5 个实例整合成完整脚本我建议你把 5 个实例分别保存成独立的.py文件而不是全部塞进一个文件里。这样每个脚本的职责清晰跑起来也方便。我个人的习惯是在一个专门的目录下建一个examples文件夹把 5 个文件依次命名为ex1_hello.py、ex2_type.py、ex3_loop.py、ex4_func.py、ex5_file.py。以实例 5 为例完整的ex5_file.py是这样的# ex5_file.py # 演示文件读写与异常处理 try: with open(data.txt, r, encodingutf-8) as f: content f.read() print(文件内容:) print(content) except FileNotFoundError: print(找不到文件 data.txt请先创建该文件) except UnicodeDecodeError: print(文件编码不是 UTF-8请检查文件编码) finally: print(文件操作尝试结束)如果没有data.txt运行结果$ python ex5_file.py 找不到文件 data.txt请先创建该文件 文件操作尝试结束如果你先创建了一个data.txt里面写上“今天是学习 Python 的一天”再运行$ python ex5_file.py 文件内容: 今天是学习 Python 的一天 文件操作尝试结束4.3 文件式处理的真正优势场景文件式的优势不只是“能保存代码”这么简单。我举一个实际例子假设你有 1 万个数据要处理交互式里你能一屏一屏地看输出但没法批量处理文件式里你可以写一个循环把这 1 万个数据全部处理完结果写入文件或者数据库。更重要的是文件式支持“渐进式开发”先写一个能跑的小功能然后慢慢加代码。比如实例 3 的循环、实例 4 的函数你可以先写一个简化版本跑通再逐步完善。这个过程在交互式里几乎不可能做到因为你每加一行代码前面的逻辑都不能复用。还有一个常被忽略的点文件式代码通过 git 等版本管理工具管理时可以做代码评审、历史回溯、多人协作。这是工程化的基础。交互式环境里敲过的代码连自己都找不回来更别说给别人 review 了。5. 5 个实例的数据对比与结果验证5.1 两种方式下 5 个实例的运行结果对照为了让对比更直观我把 5 个实例在两种方式下的运行结果放在一起。注意最终输出是完全一致的这也是很重要的一点两种方式本质上执行的是同样的 Python 代码结果当然相同不同的是操作流程和调试体验。实例核心知识点交互式运行结果文件式运行结果实例1print 输出、字符串拼接逐行立即输出文件内全部输出实例2数值计算、类型转换可看到中间计算值只看最终结果实例3for 循环、if 判断需要手动控制缩进编辑器自动管理缩进实例4函数定义与调用函数定义不可修改函数可迭代维护实例5文件读写、异常处理异常中断当前操作异常被捕获程序继续5.2 不同复杂度代码下的体验差异分析从第 1 个实例到第 5 个实例代码复杂度逐步提升两种方式的差距也越拉越大。实例 1 只有两行输出语句两种方式几乎感觉不到差别。实例 2 有一个中间计算过程交互式里你能逐步验证每一步的数学计算这在教学时是绝佳体验。实例 3 开始出现循环和缩进交互式里输入多行代码时要注意续行和缩进出错概率明显提高。实例 4 是分水岭函数定义是结构化代码交互式的“一次性”特性在这里非常不方便。实例 5 完全体现文件式的优越性错误处理逻辑需要反复修改和测试只有写在文件里才能高效迭代。5.3 为什么最终输出一致但体验不同这里要解释一个本质问题为什么两种方式跑的代码一样结果一样但体验完全不同因为交互式环境的执行粒度是“行”文件式环境的执行粒度是“文件”。交互式每输入一行代码解释器就执行一行状态在内存中持续累积文件式则是把整个文件作为一个完整的代码块从头到尾执行一遍状态在执行结束后自动释放。这就导致两个直接后果第一交互式里你可以在执行过程中随时查看中间状态文件式里要查看中间状态需要手动打印第二交互式里一行代码出错后面的代码就没法继续了文件式里可以用异常处理把错误捕获住程序继续跑。理解了这一点你就知道什么时候该用哪种方式需要逐步验证、探索数据时用交互式需要完整逻辑、异常处理、批量处理时用文件式。6. 常见问题与排查技巧实录6.1 缩进错误交互式里最常见的翻车点交互式里输入循环和函数时缩进的坑几乎每个人都踩过。典型的错误是这样 for i in range(1, 11): ... if i % 2 0: File stdin, line 2 if i % 2 0: ^ IndentationError: expected an indented block after for statement on line 1解决办法是记住在提示符...后面要先按一下 Tab 键或空格键。一般建议用 4 个空格因为不同的终端对 Tab 键的渲染方式不一样4 个空格最保险。文件式里有编辑器帮忙但如果你的编辑器设置把 Tab 键和空格混用了也会报TabError: inconsistent use of tabs and spaces in indentation。所以我统一建议代码缩进只用空格不用 Tab。VS Code 里可以通过设置editor.insertSpaces: true来强制空格。6.2 中文编码问题Windows 下的老朋友在 Windows 控制台里运行包含中文的.py文件时经常遇到类似UnicodeEncodeError: gbk codec cant encode character \u...的错误。这是因为 Windows 控制台默认用的是 GBK 编码而 Python 试着把中文字符输出到控制台时编码对不上。我常用的解决办法有两个。第一个在脚本文件第一行加注释声明编码# -*- coding: utf-8 -*-不过要注意Python 3 默认就是 UTF-8 源码编码这个声明只有在 Python 2 里才是必须的。对 Python 3 来说真正的问题在输出环节。更靠谱的办法是设置环境变量PYTHONIOENCODINGutf-8或者在代码里重新配置标准输出编码import sys import io sys.stdout io.TextIOWrapper(sys.stdout.buffer, encodingutf-8)但这里我不建议一上来就加转换代码先试试PYTHONIOENCODINGutf-8能不能解决问题如果不行再在代码里处理。另外还可以用 VS Code 的终端跑脚本它对 UTF-8 的兼容比 Windows 原生命令行好很多。6.3 路径问题文件式运行时找不到文件实例 5 里涉及读取data.txt很多新手用 VS Code 跑脚本时报FileNotFoundError但明明文件就在脚本旁边。这个问题的根源是当前工作目录不是脚本所在目录。VS Code 默认的终端工作目录是打开的项目文件夹根目录而不是脚本文件所在目录。如果你在D:\python-project\examples下创建了ex5_file.py和data.txt但打开 VS Code 时选的文件夹是D:\python-project那运行的当前目录就是D:\python-project自然找不到D:\python-project\examples下的data.txt。解决办法很简单运行前先确认当前目录用pwdLinux/macOS或cdWindows切换到脚本所在目录。或者在代码里使用绝对路径import os base_dir os.path.dirname(os.path.abspath(__file__)) data_path os.path.join(base_dir, data.txt)__file__是 Python 内置变量表示当前脚本文件的路径这个技巧在真实项目里非常实用。6.4 交互式多行输入技巧与误操作恢复再分享几个交互式环境里的小技巧。第一个多行输入时如果需要修改上一行的内容很多新手会按方向键上试图修改但发现上一条命令已经执行了没法改。这个只能重新输入没有别的办法。第二个如果输入到一半发现某个循环体写错了可以用CtrlC取消当前的整个输入块回到干净的提示符。注意CtrlC不是退出交互式环境而是中断当前输入或执行的任务只有在没有任何输入的情况下才会让解释器重新给你提示符。第三个你想重新运行之前输入过的某条命令可以用方向键上翻历史记录。这个功能在交互式里很好用比如输入了很长的类型转换语句下一次要微调数值按上箭头调出来改就行。第四个容易误触的操作是CtrlD在交互式里它相当于退出 Python。如果你在输入代码的过程中不小心按了CtrlD当前会话就结束了所有未保存的代码全部丢失。所以重要代码一定及时存成文件。6.5 混用陷阱交互式里定义的变量到文件式里不存在有人会在交互式里测试好一段代码然后复制到一个.py文件里期望得到一样的结果。大部分情况确实如此但有一种情况会出问题如果这段代码依赖了交互式环境里已经定义过的变量。举个例子你在交互式里定义了 base 100然后测试了一段 result base 50 print(result) 150你把result base 50复制到文件里运行结果报NameError: name base is not defined。这类问题在实战中很常见因为交互式环境的内存里保留了所有历史变量而文件式环境每次运行都是全新的。所以从交互式复制代码到文件时务必要检查代码是否依赖了“隐形变量”。我见过不少人在交互式里调试数据清洗代码跑得好好的一旦搬到脚本里就各种报错基本都是这个原因。7. 实操心得与拓展应用建议7.1 写代码时怎么用好这两种方式根据我自己的经验一个比较高效的流程是这样的先在交互式里快速验证函数的核心逻辑比如列表推导式的写法对不对、这个正则表达式能不能匹配到目标内容。验证通过之后再把代码整理成标准函数或脚本写入文件。这个流程的好处是交互式帮你快速过滤掉语法错误和逻辑错误文件式帮你沉淀出可复用的代码。两者配合效率和代码质量都能兼顾。7.2 交互式环境的下沉应用调试器与命令行工具交互式的方式不只体现在 Python 默认的 REPL 里很多工具和框架都有类似的交互能力。比如调试器pdb你可以设置断点然后在断点处进入一个类似交互式的环境输入代码查看变量的值。再比如 IPython 和 Jupyter Notebook本质上都是交互式思路的延伸只是 Jupyter 把“历史代码”也保存下来了某种程度上弥补了交互式代码不持久的短板。了解这一点有什么意义呢你理解了交互式的本质是“即时反馈”就能触类旁通任何提供交互界面的工具都适合同一类场景——快速探索、验证假设、调试局部问题。7.3 5 个实例可以继续扩展的方向这 5 个实例虽然简单但每一道都能往外延伸。实例 2 的类型转换可以做输入校验比如用户输入的不是数字就报错实例 3 的循环可以改成列表推导式性能会有明显提升实例 4 的函数可以加类型注解写模块化的工具库实例 5 的文件读写可以升级成 CSV 处理或日志系统。我建议你把每一个实例的扩展方向当成练习题用文件式方式去完成。比如我给自己的练习清单是这样的扩展 1把实例 2 改为接收命令行参数输入支持反复计算不同的温度值扩展 2把实例 3 的代码改成统计 1 到 100 以内的偶数和扩展 3给实例 4 的函数增加typing类型注解并调用它处理一组列表数据扩展 4把实例 5 改为写日志文件每次运行时追加一行运行记录这些练习不用太复杂目的是让你在文件式环境下反复加深对流程控制、函数封装、异常处理的理解。7.4 最终总结两种方式不是对立而是互补回到开头的问题交互式和文件式到底哪个好答案是看场景。交互式像是草稿纸适合随手演算文件式像是正式的文档适合沉淀成果。一个合格的程序员两种方式都应该熟练而且知道什么时候该切换。我个人在实际操作中体会最深的一点是不要因为交互式方便就忽略了文件式的重要性。很多初学者喜欢泡在交互式里写代码因为不用创建文件、不用考虑缩进、写完直接看到结果很爽。但一旦代码量超过十几行交互式的体验就会急剧下降。等到真正开始做项目才发现自己连“怎么把代码整理成脚本文件”都不太熟练。所以我的建议是从学 Python 第一天就开始建立文件式习惯——哪怕只是一个两行的 Hello World也先保存成.py文件再运行。等你对文件式足够熟悉了再回头用交互式做快速验证这时候你会感受到两种方式互相配合的效率提升。
返回列表