Python程序设计——函数

news2024/11/24 12:34:59

学习目标

  • 定义带形参的函数。
  • 用实参来调用函数。
  • 区分带返回值和不带返回值的函数。
  • 使用位置参数和关键字参数调用函数。
  • 通过传参数的引用值来传递参数。
  • 开发可重用代码来模块化程序,使程序易读、易调试和易维护。
  • 为可重用函数创建模块。
  • 决定变量的作用域。
  • 定义带默认参数的函数。
  • 定义一个返回多个值的函数。
  • 在软件开发中使用函数抽象的概念。
  • 用逐步求精的方法设计和实现函数。
  • 使用可重用代码简化程序。

一、引言

        函数是为实现一个操作而集合在一起的语句集。在前面的章节中,我们已经学习了像eval( "numricString")和random.randint(a,b)这样的函数。例如:当调用random.randint(a,b)函数时,系统会执行函数里的这些语句,并返回结果。在本章里,我们将学习如何定义和使用函数以及如何应用函数抽象去解决复杂的问题。

二、定义一个函数

关键点:函数定义包括函数名称、形参以及函数体。

定义函数的语法如下所示:

def functionName(list of parameters)
    # Function body

        我们来看一个用来找出两个数中哪个比较大的函数。这个函数被命名为max,它有两个参数:num1和num2,函数返回这两个数中较大的那个。图6-1解释了这个函数的组件。

        函数包括函数头和函数体。函数头以一个def关键字开始,后面紧接着函数名以及形参并以冒号结束。

        函数头中的参数被称为形式参数或简称为形参。参数就像一个占位符:当调用函数时,就将一个值传递给参数。这个值被称为实际参数或实参。参数是可选的;也就是说,函数可以不包含参数。例如:函数random.random()就不包含参数。

        某些函数有返回值,而一些其他的函数会完成要求的操作而不返回值。如果函数有返回值,则被称为带返回值的函数。

        函数体包含一个定义函数做什么的语句集。例如:函数max的函数体使用if语句来判断哪个数更大然后返回这个数的值。一个带返回值的函数需要一个使用关键字return的返回语句来返回一个值。执行return语句意味着函数的终止。

三、调用一个函数

关键点:调用一个函数来执行函数中的代码。

        在函数的定义中,定义函数要做什么。为了使用函数,必须调用它。调用函数的程序被称为调用者。根据函数是否有返回值,调用函数有两种方式。

        如果函数带有返回值,对这种函数的调用通常当作一个值处理。例如:

Targer = max(3,4)

        调用max(3,4)并将函数的结果赋值给变量larger。

        另外一个把它当作值处理的调用例子是

print(max(3,4))

        这条语句输出调用函数max(3,4)后的返回值。

        如果函数没有返回值,那么对函数的调用必须是一条语句。例如:函数print没有返回值。下面的调用就是一条语句:

print("Programming is fun! ")

注意:带返回值的函数也可以当作语句被调用。在这种情况下,函数返回值就会被忽略掉。这是很少见的,但如果函数调用者对返回值不感兴趣,这样也是允许的。

        当程序调用一个函数时,程序控制权就会转移到被调用的函数上。当执行完函数的返回语句或执行到函数结束时,被调用函数就会将程序控制权交还给调用者。

3.1、调用栈

        每次调用一个函数时,系统就会创建一个为函数存储它的参数和变量的激活记录,然后将这个激活记录放在一个被称为堆栈的内存区域。调用栈又被称为执行堆栈、运行堆栈或机器堆栈,经常被简称为堆栈。当一个函数调用另一个函数时,调用者的激活记录保持不变,然后为新函数的调用创建一个新的激活记录。当一个函数结束了它的工作之后就将程序控制权转移给它的调用者,同时从堆栈中删除它的激活记录。

        堆栈采用后进先出的方式存储激活记录。最后被调用的函数的激活记录将最先从栈里删除。假设函数m1调用m2,然后调用m3。运行时系统将m1的激活记录压人栈中,然后是将m2的激活记录压入栈中,最后是将m3的激活记录压入栈中。在完成m3的工作之后,它的激活记录被弹出栈。在完成m2的工作之后,它的激活记录被弹出栈,在完成m1的工作之后,它的激活记录被弹出栈。

四、带返回值或不带返回值的函数

关键点:函数不是一定有返回值

        注意:实际上,不管你是否使用return,所有Python的函数都将返回一个值。如果某个函数没有返回值,默认情况下,它返回一个特殊值None。因此,无返回值函数不会返回值,它也被称作None函数。None 函数可以赋值给一个变量来表明这个变量不指向任何对象。例如,如果你运行下面程序:

def sum(number1, number2) :
    total = number1 + number2
    print(sum(1,2))

        你会发现输出为None,因为sum函数没有return语句。默认情况下,它返回None。

        注意:None函数不是一定需要return语句,但它能用于终止函数并将控制权返回函数
调用者。它的语法是

return
或
return None

        这种用法很少使用,但对于改变函数的正常流程是很有用的。

五、位置参数和关键字参数

关键点:函数实参是作为位置参数和关键字参数被传递。

        函数的作用就在于它处理参数的能力。当调用函数时,需要将实参传递给形参。实参有两种类型:位置参数和关键字参数。使用位置参数要求参数按它们在函数头的顺序进行传递。例如,下面的函数输出消息n次:

def nPrintln(message, n):
    for i in range(n) :
        print (message)

        你可以使用nPrintln('a',3)输出a三次。nPrintln('a',3) 语句将a传递给message,将3传递给n,然后输出a三次。但是,语句nPrintln(3,'a') 则有不同的含义。它将3传递给message,将a传递给n。当我们调用这样的函数时,就被称为使用位置参数。实参必须和函数头中定义的形参在顺序、个数和类型上匹配。

        你也可以使用关键字参数调用函数,通过name=value的形式传递每个参数。例如:nPlintln(n=5,message="good")将5传递给n,将"good"传递给message。使用关键字参数
时,参数可以以任何顺序出现。

        位置参数和关键字参数很可能被混在一起,但位置参数不能出现在任何关键字参数之后。假设函数头是:

def f(p1, p2,p3):

你可以通过使用

f(30,p2=4,p3=10)

调用它。
但是,你通过使用

f(30,p2 = 4,10)

调用它则会出错。因为位置参数10出现在关键字参数p2=4之后。

六、通过传引用来传递参数

关键点:当你调用带参数的函数时,每个实参的引用值被传递给函数的形参。

        因为Python中的所有数据都是对象,所以对象的变量通常都是指向对象的引用。当你调用一个带参数的函数时,每个实参的引用值就被传递给形参。这在程序设计术语中被称为通过值传递。简单地说,调用函数时,实参的值就被传递给形参。这个值通常就是对象的引用值。

        如果实参是一个数字或者是一个字符串,那么不管函数中的形参有没有变化,这个实参是不受影响的。

def main():
    x=1
    print("Before the cal1,X is",x)
    increment(x)
    print("'After the cal1, x is",x)


def increment(n):
    n+=1
    print("\tn inside the function is", n)


main() # Call the main function

        如程序清单的输出,x(1)的值被传递给形参n来调用increment函数(第4行)。函数中参数n递增1,但是不论函数做什么x都不会改变。

        这样的原因是因为数字和字符串被称为不可变对象。不可变对象的内容是不能被改变的。当你将一个新数字赋值给变量时,Python 就会为这个新数字创建新对象,然后将这个新对象的引用赋值给这个变量。

七、模块化代码

关键点:模块化可以使代码易于维护和调试,并且提高代码的重用性。

        函数可以用来减少冗余的代码并提高代码的可重用性。函数也可以用来模块化代码并提高程序的质量。在Python中,你可以将函数的定义放在一个被称为模块的文件中,这种文件的后缀名是.py。之后这些模块可以被导入到程序中以便重复使用。这些模块文件应该和其他程序一起放在同一个地方。一个模块可以包含不止一个函数。一个模块的每个函数都有不同的名字。注意: turtle、random 和math是定义在Python库里的模块,这样,它们可以被导入到任何一个Python程序中。

        如果你在一个模块里定义了两个同名函数,那会出现什么情况呢?在这种情况下不会出现语法错误,但后者的优先级高。

八、变量的作用域

关键点:变量的作用域是指该变量可以在程序中被引用的范围。

        这节讨论在函数范围中变量的作用域。在函数内部定义的变量被称为局部变量。局部变量只能在函数内部被访问。局部变量的作用域从创建变量的地方开始,直到包含该变量的函数结束为止。

        在Python中,你也可以使用全局变量。它们在所有的函数之外创建,可以被所有的函数访问。

        注意:尽管允许使用全局变量,可以看到全局变量在其他程序中使用。但在一个函数中允许修改全局变量并不是一个好习惯。因为这样做可能使程序更易出错。但是,可以定义全局变量以便模块中的所有函数都能使用它。

九、默认参数

关键点: Python允许定义带默认参数值的函数。当函数被调用时无参数,那么这些默认值就会被传递给实参。

        下面代码示例演示了如何定义带默认参数值的函数以及如何调用这样的函数。

def printArea(width = 1,height = 2):
    area = width * height
    print("width:",width, "\theight:", height, "\tarea:", area)
    
printArea() # Default arguments width = 1 and height = 2
printArea(4,2.5) # Positional arguments width = 4 and height = 2.5
printArea(height = 5,width = 3) # Keyword arguments width
printArea(width = 1.2) # Default height = 2
printArea(height = 6.2) # Default width = 1

        第1行用参数width和height定义函数printArea。width的默认值是1,而height的默认值是2。第5行是在没有传递实参的情况下调用这个函数。所以,程序就将默认值1赋给width,将默认值2赋给height。第6行通过将4和6分别赋给width和height来调用这个函数。第7行通过将3和5分别赋值给width和height来调用这个函数。注意:我们也可以通过指定参数名来传递实参的值,如第8行和第9行所示。

        注意:函数可以混用默认值参数和非默认值参数。这种情况下,非默认值参数必须定义在默认值参数之前。

        注意:尽管许多语言支持在同一个模块里定 义两个同名的函数,但是Python 并不支持这个特点。通过默认参数你只可以定义函数一次,但可以通过许多不同的方式调用函数。这和在其他语言中定义同名的多个函数的效果一样。如果你在Python中定义了多个同名函数,那么后面的函数就会取代先前的函数

 十、返回多个值

关键点: Python的return语句可以返回多个值。

        Python允许函数返回多个值。下面程序清单定义了一个输人两个数并以升序返回这两个数的函数。

def sort (number1,number2) :
    if number1 < number2:
        return number1, number2
    else:
        return number2, number1


n1,n2 = sort(3,2)
print("n1 is",n1)
print("n2 is",n2)

        sort函数返回两个值。当它被调用时,你需要同时赋值传递这些返回值。

十一、函数抽象和逐步求精

关键点:函数抽象就是将函数的使用和函数的实现分开来实现的。

        软件开发的关键就是应用抽象的概念。函数抽象将函数的使用从函数的实现分离出来。一个用户程序或简称为用户,可以在不知道函数是如何实现的情况下使用函数。函数的实现细节被封装在函数内,并对调用该函数的用户隐藏。这被称为信息隐藏或封装。如果决定改变函数的实现,只要不改变函数名,用户程序就不会受影响。函数的实现对用户而言是隐藏在一个黑匣子中,如图6-5所示。

        我们已经在用户程序中使用过许多Python内置函数,并且知道如何在程序中编写代码来调用这些函数,但是,作为这些函数的使用者,我们并不需要知道它们是如何实现的。

        函数抽象的概念可以被应用到开发程序的过程中。当编写一个大程序时,你可以使用分治策略,也称之为逐步求精,将大问题分解为子问题。这些子问题又被分为更小更容易管理的问题。

十二、总结

  • 1.程序模块化和可重用性是软件工程的中心目标之一。函数可以实现这个目标。
  • 2.函数头由关键字def开始,接下来是函数名和形式参数,最后以冒号结束。
  • 3.形式参数是可选的;也就是说,函数可以不包含任何形式参数。
  • 4.无返回值的函数被称为void或None函数。
  • 5.一个return语句可以在void函数中用来终止函数并将程序控制权返回给函数的调用者。有时,这对保证函数控制流正常是非常有用的。
  • 6.传给函数的参数必须和定义在函数头里的形参在数目、类型和顺序上保持一-致。
  • 7.当程序调用一个函数时,程序的控制权就转移到被调用的函数。当执行到函数的return语句或执行到函数的最后一条语句时,被调用的函数就将控制权转给调用者。
  • 8.带返回值函数也可以当作Python语句被调用。在这种情况下,函数的返回值被忽略。
  • 9.函数参数可以当作位置参数或关键字参数传递。
  • 10.当调用一个带形式参数的函数时,实参的值就被传给形参。这用程序设计术语讲就是值传递。
  • 11.函数中创建的变量被称为局部变量。局部变量的作用域从它被创建的位置开始,直到函数返回为止都存在。变量必须在使用前被创建。
  • 12.全局变量被定义在所有函数之外,而且它们可以被所有函数访问。
  • 13. Python允许用默认参数值定义函数。当无参数调用函数时,默认值就被传给形参。
  • 14. Python的return语句可以返回多个值。
  • 15.函数抽象是通过将函数的使用和实现分开实现。一个用户可以在不知道函数是如何实现的情况下使用函数。函数的实现细节被封装在函数内,并对调用该函数的用户来说是隐藏的。这被称为信息隐藏或封装。
  • 16.函数抽象将程序模块化为整齐、分层的形式。程序被写成简洁函数的集合,这样使程序更易于编写、调试、维护和修改。这种编写风格会提高函数的可重用性。
  • 17.当实现一个大程序时,使用自顶向下或自底向上的编码方法。不要一次性编写整个程序。这个方法似乎要占用更多的编码时间(因为要反复地运行这个程序),但它实际上更省时间和更易于调试。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/882236.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

纷享销客位列“2023企业客户关系管理(CRM)服务TOP10”第一名

近日&#xff0c;《互联网周刊》&eNet研究院发布“2023企业客户关系管理(CRM)服务TOP10”榜单&#xff0c;纷享销客连接型CRM凭借出色的产品实力和服务实践&#xff0c;位居 CRM企业排名首位。 2023年&#xff0c;穿越周期&#xff0c;用数字化的力量重塑企业经营与增长的逻…

cesium加载天地图

成果图 源码 const tiandituTk 你的tokenvar viewer new Cesium.Viewer("cesiumContainer", {imageryProvider: new Cesium.WebMapTileServiceImageryProvider({url: "http://t0.tianditu.com/img_w/wmts?servicewmts&requestGetTile&version1.0.0&a…

Win10设置代理操作步骤

1、依次点击打开控制面板--》网络和internet-》internet选项 2、选择“连接”--》点击打开局域网设置 3、勾选“为LAN使用代理服务器”&#xff0c;并根据自己需要设置地址和端口&#xff0c;点击【确定】按钮保存即可 4、使用完后千万记得关闭代理&#xff08;即取消勾选上一步…

alertmanager创建nginx-ingress basic auth鉴权

步骤 生成密码 printf "admin:$(openssl passwd -crypt xxxxxx)\n" >> auth 创建新的 Kubernetes 密钥 kubectl create secret generic basic-auth --from-file auth -n victoria-metrics 修改 ingress 以使用 secret 中的凭证来实现基本身份验证 编辑 P…

RabbitMQ和JMeter,一个完美的组合!优化你的中间件处理方式

RabbitMQ是实现了高级消息队列协议&#xff08;AMQP&#xff09;的开源消息中间件&#xff0c;它是基于Erlang语言编写的&#xff0c;并发能力强&#xff0c;性能好&#xff0c;是目前主流的消息队列中间件之一。 RabbitMQ的安装可参照官网&#xff08; https://www.rabbitmq.c…

每日汇评:黄金在 200 日移动平均线附近似乎很脆弱,关注美国零售销售

1、金价预计将巩固其近期跌势&#xff0c;至 6 月初以来的最低水平&#xff1b; 2、对美联储再次加息的押注继续限制了贵金属的上涨&#xff1b; 3、金融市场现在期待美国零售销售报告带来一些有意义的推动&#xff1b; 周二金价难以获得任何有意义的牵引力&#xff0c;并在…

JAVA毕业设计094—基于Java+Springboot+Vue的人事管理系统(源码+数据库+8000字论文)

基于JavaSpringbootVue的人事管理系统(源码数据库8000字论文)094 一、系统介绍 本系统前后端分离 本系统分为管理员、HR、员工三种角色 用户角色包含以下功能&#xff1a; 登录、个人培训、个人奖惩、个人调动、员工打卡、个人中心、密码修改、在线聊天 HR角色包含以下功…

【C++】开源:跨平台Excel处理库-libxlsxwriter配置使用

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍Excel处理库-libxlsxwriter配置使用。 无专精则不能成&#xff0c;无涉猎则不能通。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&…

达梦数据库dbms_stats包的操作实践记录

索引的统计信息收集 GATHER_INDEX_STATSindex_stats_show 根据模式名&#xff0c;索引名获得该索引的统计信息。用于经过 GATHER_TABLE_STATS、GATHER_INDEX_STATS 或 GATHER_SCHEMA_STATS 收集之后展示。返回两个结果集&#xff1a;一个是索引的统计信息&#xff1b;另一个是…

23款奔驰S400商务型升级原厂HUD抬头显示系统,增加您的行车安全

HUD是平视显示器的简称&#xff0c;它原先是运用在航空器上的飞行辅助仪器。指飞行员不需要低头&#xff0c;就能够看到他需要的重要资讯。由于HUD的方便性以及能够提高飞行安全&#xff0c;这项技术后来也发展到汽车行业。汽车搭载的HUD抬头数字显示功能&#xff0c;是利用光学…

Evaluation Warning: The document was created with Spire.Doc for JAVA.

spire.doc-5.4.10.jar 生成PDF有广告语水印【Evaluation Warning: The document was created with Spire.Doc for JAVA.】 <!-- maven库访问不了 https://mvnrepository.com/artifact/e-iceblue/spire.doc e-iceblue库才能访问 https://repo.e-iceblue.cn/repository/maven…

用于弥散加权MRI的关节各向异性维纳滤光片研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

使用chatGPT-4 畅聊量子物理学(三)

集合了人类智慧的照片&#xff0c;来自 1927 年举行的第五届索尔维国际会议。 Omer 什么是“物理系统在被测量之前不具有确定的属性。量子力学只能预测给定测量的可能结果的概率分布" ChatGPT 这句话描述了量子力学中的一种基本原则&#xff0c;即“物理系统在被测量之前…

如何优雅的使用Mock Server

事出有因 昨天跟同事讨论我们在用的rap2(一个集接口编写和mock server的开源项目)和刚上线了一个easy-mock的server&#xff0c;到底哪个好用。 我们主要讨论的点有个两个&#xff1a; 接口的一致性、 编码的无侵入性。 背景 自从前后端分离后&#xff0c;完成前后端的分工…

Netty:用ByteBufUtil的函数将字节数组、或者ByteBuf的内容转换为十六进制表示的字符串

用ByteBufUtil的hexDump(byte[] array)函数将字节数组的内容转换为十六进制表示的字符串 package com.thb;import io.netty.buffer.ByteBufUtil;public class Demo {public static void main(String[] args) {byte[] b new byte[] {0x68, 0x16, 0x03, 0x04, (byte)0xae};Stri…

6 个简单步骤,教你创建可视化看板工作流

看板是一种相当流行的工作管理工具&#xff0c;团队和组织使用它来可视化工作流程&#xff0c;限制当前正在进行的工作&#xff0c;并最大限度地提高流程效率。 看板的一些主要特点包括&#xff1a; ✓ 看板提供了对工作流程进行可视化控制的手段&#xff1b; ✓ 看板 "…

迭代器(Iterator)与 ListIterator 的使用

目录 一. Iterator 接口 例子&#xff1a; 二. ListIterator 接口 三. Iterable 接口 例子&#xff1a; 四. List 接口 五. Iterable接口 与 Iterator 接口 在 ArrayList 中 的使用 六. List 接口 与 ListIterator 接口 在 ArrayList 中 的使用 一. Iterator 接口 Ite…

网址生成二维码要怎么实现?1分钟教程来啦!

将网址链接转换成一个二维码&#xff0c;方法很简单。 今年六月份&#xff0c;海澜之家在父亲节的活动中&#xff0c;就使用了一个网址链接二维码。扫描地铁站内的海报上的二维码&#xff0c;就能跳转到一篇海澜之家的微信公众号文章里&#xff0c;查看100个父亲的故事。 其实…

网络电视盒子哪个好?回购率最高电视盒排行榜揭晓!

在挑选电视盒子的时候&#xff0c;我们不能光看配置&#xff0c;也要看系统优化、广告植入等方面&#xff0c;不知道网络电视盒子哪个好&#xff0c;可以借鉴目前业内最新发布的电视盒子回购率排行榜&#xff0c;看看目前用户口碑最好的是哪些机型。 ●泰捷WEBOX 60Pro电视盒子…

PyTorch从零开始实现ResNet

文章目录 代码实现参考 代码实现 本文实现 ResNet原论文 Deep Residual Learning for Image Recognition 中的50层&#xff0c;101层和152层残差连接。 代码中使用基础残差块这个概念&#xff0c;这里的基础残差块指的是上图中红色矩形圈出的内容&#xff1a;从上到下分别使用…