最近我在学 Python 编程,今天可算是狠狠钻研了一把 Python 里的函数,感觉脑袋里的知识又充实了不少,赶紧来记一记。
一、Python函数基础概念
(一)pass语句:代码块的“占位符”
在编写代码时,有时我们需要在代码块中预留位置,但暂时不想执行任何操作,这时pass
语句就派上用场啦。它就像是一个空语句,默默地占据着代码的位置,让代码结构保持完整。比如在条件语句、循环语句或者函数定义中,都可以使用pass
语句来占位。
(二)函数定义与调用:代码复用的关键
函数是一段可复用的代码块,专门用来执行特定的任务。定义函数时,我们要使用def
关键字,就像给这个“小助手”取了个名字,然后在后面加上参数列表(如果有的话)和代码块。调用函数也很简单,直接使用函数名并传入相应的参数就可以啦。函数可以接受参数,还能返回结果,返回结果时使用return
语句。
二、参数传递:灵活赋予函数“能量”
(一)位置实参:按顺序传递的“接力棒”
位置实参是最常见的参数传递方式,它按照参数在函数定义中的位置顺序进行传递。就像接力比赛中的接力棒,每个实参都要准确地交到对应的形参“手中”,顺序不能错,数量也要对应。这种方式要求实参的位置必须与形参完全一致,是必须传递的参数。
(二)关键字实参:清晰明确的“指令”
关键字实参通过指定形参的名称来传递实参,这样做的好处是让函数调用更加清晰易懂。我们可以按照任意顺序传递关键字实参,而且它还能和位置参数混合使用呢!不过要记住,位置参数得放在前面。在只需要传递部分参数的情况下,关键字实参就非常方便啦。
(三)默认实参:贴心的“预设方案”
在定义函数时,我们可以给形参设置默认值,这就是默认实参。有默认值的形参要放在没有默认值的形参后面哦。调用函数时,如果不传递这个参数,它就会使用默认值;要是传递了实参,实参的值就会覆盖默认值。默认实参常用于设置一些可选参数,让函数的使用更加灵活。
(四)可变数量实参:包容万物的“收纳盒”
可变数量实参允许我们向函数传递任意数量的实参。其中,非关键字实参会被封装成一个元组,关键字实参会被封装成一个字典。可变数量实参可以和其他参数类型混合使用,不过位置参数还是要放在前面。
三、作用域:变量的“活动范围”
(一)作用域分类:各司其职的“小天地”
- 全局作用域:在函数外部定义的变量就处于全局作用域,就像住在“大房子”里的居民,程序的各个地方都能访问到它们。
- 局部作用域:函数或类方法内部定义的变量在局部作用域中,这是它们自己的“小房间”,只有在所属的代码块内才能被看到和使用。
- 嵌套作用域:当代码块层层嵌套时,就会产生嵌套作用域。内部代码块可以访问外部代码块的变量,就像在嵌套的房间里,里面的人可以看到外面房间的东西,但外面的人看不到里面的。
- 内置作用域:这是Python预先定义好的变量和函数名的“领地”,我们可以直接使用,非常方便。
(二)作用域访问规则:严格遵守的“规定”
局部作用域的变量可以访问局部、嵌套和全局作用域的变量;嵌套作用域的变量能访问嵌套和全局作用域的变量,但不能修改全局变量;全局作用域只能访问全局变量,没办法直接修改局部和嵌套作用域的变量。如果想要在函数内部修改全局变量,就得使用global
关键字。
四、特殊函数:强大而独特的“编程利器”
(一)匿名函数(lambda函数):小巧灵活的“短兵器”
匿名函数,也就是lambda
函数,它没有函数名,通常只包含一个表达式。这种函数就像一把小巧灵活的“短兵器”,适合用来创建一些简单的函数,在需要的地方直接使用,非常便捷。
(二)map函数:高效的“批量处理器”
map
函数是Python的内置函数,它就像一个高效的“批量处理器”,可以对可迭代对象(比如列表、元组)中的每个元素应用同一个函数,然后返回一个结果列表。
(三)filter函数:精准的“筛选器”
filter
函数就像一个精准的“筛选器”,它能从可迭代对象中筛选出满足特定条件的元素,最后返回一个迭代器,里面装着筛选出来的元素。
(四)reduce函数:强大的“累积计算器”
reduce
函数有点像一个强大的“累积计算器”,它会将指定的函数应用于可迭代对象的前两个元素,然后用计算结果再和下一个元素继续应用这个函数,不断累积计算。不过,使用reduce
函数需要从functools
模块导入哦。
(五)递归函数:自我调用的“解题高手”
递归函数是一种特殊的函数,它通过调用自身来解决问题。就像一个聪明的“解题高手”,把大问题一步步分解成小问题。递归函数由终止条件和内部调用自身这两部分组成。使用递归函数时要特别注意,一定要有终止条件,避免出现无限调用的情况,而且每次调用都要朝着终止条件靠近。
五、实战练习:在实践中成长
(一)课堂练习:小试牛刀
- 递归实现阶乘计算:要求使用递归函数实现输入5输出5 * 4 * 3 * 2 * 1的值。这就需要我们巧妙地运用递归函数的特性,通过不断调用自身,逐步计算出阶乘的结果。
- 猴子吃桃问题:这个问题也可以用递归的方法来解决。我们要根据猴子每天吃桃的规律,从后往前推算出第一天桃子的数量。
(二)作业挑战:提升技能
- 斐波那契数列编程:用递归编程实现斐波那契数列,这是一个经典的递归应用场景。斐波那契数列的特点是从第三项开始,每一项都等于前两项之和,通过递归函数可以很好地实现这个逻辑。
- 计算5个人年龄问题:根据每个人年龄之间的关系,使用递归函数计算出第5个人的年龄。这需要我们理清年龄之间的递归关系,准确地编写递归函数。
- 汉诺塔扩展作业:汉诺塔问题是一个更具挑战性的递归应用。我们要通过递归算法,实现将一叠盘子从一个柱子借助另一个柱子移动到第三个柱子,并且要遵循特定的规则。
Python函数是Python编程中非常重要的一部分,掌握了函数的各种知识,我们就能编写出更加简洁、高效、灵活的代码。希望大家通过今天的学习,对Python函数有更深入的理解,在编程的道路上不断进步!
日记 & 总结
一开始接触函数基础概念的时候,我就被pass语句给绊了一下。这pass语句,你说它啥都不干吧,但又不能少了它。就好比盖房子,有些地方暂时还没打算装修,但又不能让它空着不管,pass语句就像是给这个地方放了个 “占位牌”,先占着位置,等以后想好了再填内容。在条件语句、循环语句或者函数定义里,它都能发挥这个作用,虽然不起眼,但还挺重要的。
函数的定义和调用也挺有意思。定义函数就像是打造一个多功能小工具,用def关键字给它取个名字,再根据需要给它装上不同的 “零件”—— 参数。这个小工具做好了,调用它的时候就像拿起工具开始干活,把需要的数据作为参数传进去,它就能帮我们完成特定的任务。要是这个任务完成后有结果,就用return语句把结果 “交出来”。
说到参数传递,这里面的门道可多了。位置实参就像是排队,大家得按照顺序来,一个萝卜一个坑,顺序和数量都不能错,不然这个 “小工具” 可能就没法正常工作。关键字实参呢,就灵活多了,它可以不按顺序来,只要喊对形参的 “名字”,把数据传过去就行,就像在一群人里直接喊名字找对应的人,这样函数调用起来就清晰多了。而且它还能和位置参数一起用,不过位置参数得站前面。
默认实参就更贴心啦,就像给 “小工具” 设置了一些常用的默认配置。定义函数的时候给形参设置好默认值,调用的时候要是不想改这个配置,就可以直接用默认的;要是有特殊需求,再传个新的值进去,把默认值替换掉就行。这在设置一些可选参数的时候特别方便,感觉就像是给我们开了个 “便捷通道”。
还有可变数量实参,这简直就是个 “大胃王”,能装下任意数量的实参。非关键字实参传进来后会被打包成一个元组,关键字实参则会被装进一个字典里。它还能和其他参数类型一起搭配使用,不过位置参数还是得打头阵。
函数的作用域也让我费了不少脑筋。全局作用域里的变量就像是住在 “大别墅” 里,整个程序都能找到它们,随时可以用。局部作用域的变量就像是在每个 “小房间”(函数或类方法内部)里的私人物品,只有在这个 “小房间” 里才能看到和使用。嵌套作用域有点像 “套娃”,里面的 “小套娃”(内部代码块)能看到外面 “大套娃”(外部代码块)的东西,但外面的看不到里面的。
内置作用域就像是 Python 提前准备好的 “百宝箱”,里面的变量和函数名我们直接就能用,可方便了。不过不同作用域之间的访问规则得记清楚,局部作用域能访问好多地方的变量,但嵌套作用域不能随便修改全局变量,全局作用域也动不了局部和嵌套作用域的变量。要是真想在函数里改全局变量,那就得请出global关键字来帮忙。
特殊函数这部分,我觉得匿名函数(lambda函数)特别酷,它没有名字,就像个神秘的 “小刺客”,通常就一个表达式,简单又灵活,适合在一些小场景里快速解决问题。
map函数是个高效的 “流水线工人”,能把同一个操作应用到可迭代对象的每个元素上,然后整齐地返回一个结果列表。filter函数则是个严格的 “质检员”,从可迭代对象里挑出符合条件的元素,组成一个新的迭代器。
reduce函数就像个厉害的 “数学家”,能把函数一步步应用到可迭代对象的元素上,不断累积计算,不过用它得先从functools模块把它 “请” 出来。递归函数最神奇,它能自己调用自己,就像一个人能不断地给自己布置新任务,直到完成最终目标。但用它的时候得小心,一定要有个终止条件,不然就像掉进了一个无尽的循环陷阱里,而且每次调用都得离这个终止条件更近一点。
今天还做了不少练习和作业。课堂上用递归函数计算阶乘,一开始我完全摸不着头脑,后来慢慢理解了递归的逻辑,顺着这个思路就把代码写出来了。还有猴子吃桃的问题,也是用递归解决的,从最后一天剩下的桃子数往前倒推,算出第一天的桃子数量,解开这个问题的时候可太有成就感了。作业里有斐波那契数列的编程、计算 5 个人年龄的问题,还有汉诺塔的扩展作业,这些可把我折腾坏了,但也让我对递归函数有了更深的理解。
今天学的这些内容虽然有点烧脑,但学会之后真的超有成就感。感觉自己在 Python 编程的路上又迈进了一大步,以后还要继续加油,多练习,把这些知识掌握得更牢固!