ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Python学习第七天:函数与模块的分水岭,零基础如何突破

Python学习第七天:函数与模块的分水岭,零基础如何突破 1. 第七天为什么是Python学习的分水岭1.1 从照着敲到自己写的临界点如果你正在按天打卡学Python第七天大概率会撞上一堵墙。前六天你可能已经搞定了环境安装、变量、数据类型、条件判断和循环敲过的代码加起来也有几百行了。但到了第七天很多人会突然发现照着教程敲能跑通关掉教程自己写就卡壳。这不是你笨而是学习路径到了必须换挡的位置。我带了不下二十个零基础转行的朋友入门Python几乎所有人都在第六到第八天之间出现明显的分化。一部分人继续往前冲开始写小工具、爬数据、做可视化另一部分人卡在函数和模块这两个概念上反复看视频反复忘。分水岭的核心不在于智商而在于第七天你有没有把函数定义、参数传递、模块导入这三件事真正吃透。第七天的典型内容通常包括函数的定义与调用、参数类型位置参数、默认参数、关键字参数、可变参数、返回值、变量作用域以及模块和包的基本使用。这些内容看起来零散实际上是一条主线——把重复代码封装起来把功能拆分成独立单元。这条主线一旦打通后面学爬虫、数据分析、可视化界面都会顺很多。1.2 第七天该达到什么水平才算过关先给一个可量化的自测标准你可以对照检查自己是否真的过了第七天这一关能独立写出一个带参数、带返回值的函数并解释每个参数的作用能说清楚return和print的区别知道什么时候用哪个能理解if __name__ __main__:这行代码到底在干什么能自己创建一个.py文件当作模块在另一个文件里导入并使用遇到NameError、TypeError、IndentationError能自己定位问题这五条如果都能做到第七天就算真正过关了。做不到也没关系下面我会把每个点拆开讲配上我实际教学中验证过的例子和踩坑记录。提示第七天不要贪多去碰装饰器、生成器、协程这些进阶内容。先把函数和模块的基础打牢后面学python协程、python量化交易策略代码这类内容时才有底气。2. 函数把代码装进盒子的第一课2.1 为什么必须学函数而不是继续堆代码前六天写的代码基本是流水账——从上到下一条条执行。这种写法在几十行以内没问题但一旦超过一百行就会出现三个致命问题重复代码多、修改成本高、调试困难。举个我常用来教学的例子。假设你要计算三个不同半径的圆的面积r1 3 area1 3.14159 * r1 * r1 print(area1) r2 5 area2 3.14159 * r2 * r2 print(area2) r3 7 area3 3.14159 * r3 * r3 print(area3)这段代码能跑但公式重复了三遍。如果哪天圆周率要精确到更多位你得改三个地方。用函数改写def circle_area(radius): pi 3.14159 return pi * radius * radius print(circle_area(3)) print(circle_area(5)) print(circle_area(7))改动只有一个地方逻辑清晰还能反复调用。这就是函数的本质——给一段逻辑起个名字需要的时候喊一声就行。生活里的类比就是你不会每次做饭都重新发明切菜这个动作而是把它定义成一个固定流程需要时直接调用。2.2 参数传递的四种姿势与选择逻辑函数的参数是第七天最容易混淆的部分。Python的参数类型比很多语言灵活灵活就意味着容易用错。我把四种参数按使用频率和重要性排个序参数类型写法示例典型场景注意事项位置参数def f(a, b)参数少且顺序固定调用时顺序不能错默认参数def f(a, b10)有常用默认值的场景默认参数必须放最后关键字参数f(a1, b2)参数多、易混淆时提高可读性可变参数def f(*args, **kwargs)参数数量不确定别滥用会降低可读性默认参数有一个经典陷阱我见过太多人栽在这里def add_item(item, target_list[]): target_list.append(item) return target_list print(add_item(1)) # [1] print(add_item(2)) # [1, 2] 不是 [2]原因是默认参数[]在函数定义时只创建一次所有调用共享同一个列表。正确写法是用None做占位def add_item(item, target_listNone): if target_list is None: target_list [] target_list.append(item) return target_list这个坑在面试和实际项目里都高频出现第七天记住它能省掉后面无数调试时间。2.3 return和print到底差在哪新手最常见的困惑之一return和print看起来都能输出结果到底有什么区别我用一句话概括print是给人看的return是给程序用的。def add_print(a, b): print(a b) def add_return(a, b): return a b result1 add_print(1, 2) # 屏幕显示3但result1是None result2 add_return(1, 2) # 屏幕无显示但result2是3print只是把值显示在终端函数本身没有产出return才是把计算结果交回给调用者。如果你写的函数结果还要参与后续计算必须用return。我见过有人的爬虫代码里全是print结果数据没法传给下一步做可视化只能推倒重写。一个函数可以没有return此时默认返回None。也可以返回多个值本质上是返回一个元组def min_max(numbers): return min(numbers), max(numbers) low, high min_max([3, 1, 4, 1, 5]) print(low, high) # 1 52.4 变量作用域为什么函数里的变量外面用不了作用域这个概念第七天必须建立清晰的心智模型。简单说函数内部定义的变量函数外部访问不到。def greet(): message hello print(message) greet() # 正常输出 hello print(message) # NameError: name message is not defined这个规则的意义在于隔离。每个函数像一个独立房间房间里的东西不会跑到外面干扰别人。如果确实需要函数影响外部有两种方式一是通过return把值传出来二是用global声明全局变量但强烈不建议滥用。count 0 def increment(): global count count 1 increment() print(count) # 1global能不用就不用它会让代码的依赖关系变得隐蔽调试时很难追踪谁改了变量。我个人的经验是能用参数和返回值解决的绝不碰global。3. 模块与包从单文件走向工程化3.1 为什么第七天必须理解模块前六天所有代码都写在一个文件里第七天开始要接触模块这个概念。模块说白了就是一个.py文件里面定义了一堆函数和变量可以被其他文件导入使用。为什么需要模块因为一个项目不可能所有代码都塞进一个文件。想象一下你写一个爬虫项目网络请求、数据解析、存储、可视化全写在一起文件上千行改一个地方要翻半天。拆成模块后每个文件负责一件事维护成本直线下降。创建模块非常简单新建一个tools.py# tools.py def add(a, b): return a b def multiply(a, b): return a * b PI 3.14159在另一个文件里导入# main.py import tools print(tools.add(1, 2)) print(tools.PI)也可以只导入需要的部分from tools import add, PI print(add(3, 4)) print(PI)3.2 import的几种写法和使用场景导入方式有好几种各有适用场景选错了会让代码可读性变差import tools最推荐来源清晰tools.add()一眼知道来自哪里from tools import add适合频繁调用某个函数但函数多了容易混淆来源from tools import *强烈不推荐会污染命名空间还可能覆盖同名变量import tools as t给长模块名起别名比如import numpy as np就是行业惯例我个人的原则是标准库和第三方库用别名导入如import pandas as pd自己写的模块用完整导入。这样代码里一眼就能区分哪些是外部依赖哪些是项目内部代码。3.3if __name__ __main__到底在防什么这行代码几乎是每个Python教程都会提到但很多人学完也不知道它干嘛用的。我用一个具体场景解释。假设tools.py里除了函数定义还写了一段测试代码# tools.py def add(a, b): return a b print(测试:, add(1, 2))当你在main.py里import tools时那句print也会被执行屏幕上莫名其妙多出一行测试: 3。这不是你想要的。加上判断后就干净了# tools.py def add(a, b): return a b if __name__ __main__: print(测试:, add(1, 2))原理是当文件被直接运行时__name__的值是__main__当文件被导入时__name__的值是模块名这里是tools。所以这个判断的作用是——只在直接运行时执行测试代码被导入时不执行。提示养成习惯每个.py文件都加上这个判断把测试代码放在里面。这是从写脚本到写项目的重要一步。3.4 包的概念与目录结构模块多了之后需要用一个文件夹把它们组织起来这个文件夹就是包。包的标准结构是myproject/ ├── main.py ├── utils/ │ ├── __init__.py │ ├── math_tools.py │ └── string_tools.py └── data/ └── config.py__init__.py文件的存在标志着这个文件夹是一个包Python 3.3之后可以省略但建议保留。导入包内模块from utils import math_tools from utils.math_tools import add第七天不需要把包玩得很溜但要知道这个结构的存在。后面学python爬虫可视化界面、python数据分析与可视化这类项目时代码一定会按包来组织提前建立认知能少走弯路。4. 第七天的实操项目一个能跑的小工具4.1 项目设计命令行单位换算器光看概念容易忘第七天必须动手写一个完整的小项目。我推荐做命令行单位换算器因为它用到了函数、参数、返回值、模块导入正好覆盖第七天的全部知识点而且逻辑简单不会卡住。需求如下支持长度换算米、厘米、千米、英寸支持温度换算摄氏度、华氏度支持重量换算千克、克、磅用函数封装每种换算逻辑拆成模块主程序负责交互4.2 核心代码实现与逐段解析先写换算模块converter.py# converter.py def meter_to_cm(m): return m * 100 def cm_to_meter(cm): return cm / 100 def km_to_meter(km): return km * 1000 def inch_to_cm(inch): return inch * 2.54 def celsius_to_fahrenheit(c): return c * 9 / 5 32 def fahrenheit_to_celsius(f): return (f - 32) * 5 / 9 def kg_to_g(kg): return kg * 1000 def pound_to_kg(pound): return pound * 0.45359237每个函数只做一件事参数和返回值都明确。这种写法叫单一职责是函数设计的基本原则。你可能会觉得函数太短没必要封装但正是这种短函数最容易测试和复用。再写主程序main.py# main.py from converter import ( meter_to_cm, cm_to_meter, km_to_meter, inch_to_cm, celsius_to_fahrenheit, fahrenheit_to_celsius, kg_to_g, pound_to_kg ) def show_menu(): print(1. 米 - 厘米) print(2. 厘米 - 米) print(3. 千米 - 米) print(4. 英寸 - 厘米) print(5. 摄氏度 - 华氏度) print(6. 华氏度 - 摄氏度) print(7. 千克 - 克) print(8. 磅 - 千克) print(0. 退出) def main(): while True: show_menu() choice input(请选择: ).strip() if choice 0: print(再见) break if choice not in [str(i) for i in range(1, 9)]: print(无效选择请重新输入) continue try: value float(input(请输入数值: )) except ValueError: print(请输入合法数字) continue result dispatch(choice, value) print(f结果: {result}) def dispatch(choice, value): if choice 1: return meter_to_cm(value) elif choice 2: return cm_to_meter(value) elif choice 3: return km_to_meter(value) elif choice 4: return inch_to_cm(value) elif choice 5: return celsius_to_fahrenheit(value) elif choice 6: return fahrenheit_to_celsius(value) elif choice 7: return kg_to_g(value) elif choice 8: return pound_to_kg(value) if __name__ __main__: main()4.3 关键设计决策背后的思考这个项目里有几个设计选择值得说明理解了它们你写其他项目时也能举一反三。为什么把换算逻辑和交互逻辑分开因为换算逻辑是纯计算不依赖输入输出可以单独测试交互逻辑涉及input和print测试起来麻烦。分开后如果哪天要做图形界面换算模块可以原封不动复用。为什么用dispatch函数而不是一长串if-else其实一长串if-else也能跑但抽成独立函数后main函数的逻辑更清晰只负责拿输入、调分发、显示结果。这是关注点分离的体现。为什么用try-except包住float转换因为用户可能输入abc直接float(abc)会抛ValueError导致程序崩溃。加上异常处理后程序会提示重新输入而不是退出。这是健壮性的基本要求。为什么用f-string而不是字符串拼接f结果: {result}比结果: str(result)更简洁而且性能更好。Python 3.6之后f-string是格式化输出的首选。4.4 运行效果与扩展方向运行python main.py你会看到菜单输入数字选择换算类型再输入数值就能得到结果。整个过程用到了第七天学的所有知识点函数定义、参数、返回值、模块导入、__main__判断。这个项目后续可以往几个方向扩展加入更多单位面积、体积、速度用字典替代if-else分发代码更简洁加一个历史记录功能把每次换算结果存到列表里用argparse模块支持命令行参数比如python main.py --type length --value 100用tkinter或flet做成图形界面提示扩展方向里提到的python flet是近几年比较火的跨平台UI框架能打包成桌面应用甚至APK。等你把函数和模块玩熟了可以拿这个换算器练手做界面。5. 第七天高频报错与排查手册5.1 报错速查表第七天遇到的报错基本集中在几类我整理成表格方便对照报错信息常见原因解决方法NameError: name xxx is not defined变量名拼错、作用域问题、忘记导入检查拼写确认变量在作用域内补上importTypeError: f() missing 1 required positional argument调用函数时参数数量不对对照函数定义检查参数个数TypeError: can only concatenate str (not int) to str字符串和数字直接相加用str()转换或改用f-stringIndentationError: expected an indented block缩进错误检查冒号后是否缩进统一用4个空格ModuleNotFoundError: No module named xxx模块名拼错或未安装检查拼写第三方库用pip安装ValueError: could not convert string to float输入不是合法数字用try-except处理或校验输入5.2 三个我踩过的真实坑坑一函数名和变量名冲突。我曾经写过一个函数叫list结果后面调用内置的list()就报错了。Python允许你覆盖内置函数名但后果是原来的功能没了。永远不要用list、str、int、sum、max这些内置名当变量或函数名。坑二默认参数的时机问题。前面讲过的可变默认参数陷阱我在一个批量处理数据的脚本里栽过。函数默认参数是空列表结果多次调用后数据全堆在一起排查了半小时才发现。记住默认参数只在定义时求值一次。坑三循环导入。当两个模块互相import对方时会报ImportError或出现部分功能不可用。解决办法是把公共部分抽到第三个模块或者把导入语句放到函数内部延迟导入。第七天项目小不容易遇到但要知道这个坑的存在。5.3 调试函数的三板斧函数出问题时我通常按这个顺序排查打印参数在函数开头print一下传入的参数确认值对不对打印中间结果在关键计算步骤后print看哪一步开始不对单独测试把函数复制到一个干净的.py文件里用固定输入测试排除其他代码干扰这三招看起来笨但比盯着代码干想要高效得多。等后面学了pdb调试器或IDE的断点调试效率会更高但第七天用print足够。6. 第七天之后的路怎么走6.1 别急着跳进爬虫和数据分析我见过太多人在第七天之后直接冲去学python爬虫教程结果因为函数和模块没打牢写出来的爬虫代码全堆在一个文件里几百行没法维护。爬虫、数据分析、可视化这些方向本质上都是函数和模块的组合应用。基础不牢学得越快忘得越快。我的建议是第七天之后再用两三天时间把函数和模块练熟。具体做法把之前六天写的所有练习代码用函数重新组织一遍每个功能拆成独立函数加上参数和返回值把相关的函数归类到不同模块里写一个主程序把它们串起来这个过程叫重构是提升代码能力最快的方式。重构一遍比新学三个知识点收获还大。6.2 环境与工具方面的提醒第七天你可能已经在用VS Code或PyCharm了。关于vscode python环境配置和pycharm配置python环境有几点经验分享VS Code配置Python环境核心是选对解释器CtrlShiftP搜Python: Select Interpreter以及装好Python扩展PyCharm新建项目时注意选对解释器虚拟环境建议用venv别用系统Python如果遇到cannot be resolved against python helper roots这类提示通常是解释器没选对或扩展没装好重新选一次解释器基本能解决国内下载第三方库慢的话可以配置国内源比如清华源或阿里源pip install时加-i参数指定这些工具配置问题在第七天前后高频出现配好了能省很多事。但记住工具是辅助核心还是代码逻辑。6.3 一个我常给新人的练习清单最后分享一份我给零基础朋友准备的第七天练习清单按难度递增写一个函数接收一个列表返回其中的最大值和最小值写一个函数判断一个字符串是不是回文写一个模块包含三个函数求阶乘、求斐波那契数列第n项、判断素数写一个主程序导入上面的模块让用户选择执行哪个功能把单位换算器项目加上历史记录功能用列表存储每次结果尝试用字典替代if-else实现分发逻辑这六道题做完第七天的知识点就真正内化了。别小看这些练习它们覆盖了函数设计、参数传递、返回值、模块导入、异常处理、数据结构综合运用是后面所有Python项目的基石。我个人在实际教学中的体会是第七天慢一点后面快很多。那些急着跳过函数和模块直接学框架的人往往在第十几天又回来补课。与其返工不如现在就把这块啃透。函数和模块是Python世界里最基本的积木积木搭得稳后面盖什么楼都不慌。
返回列表