备考计算机二级Python之Day5

news2024/12/26 16:42:36

第5章 函数和代码

一、函数的基本使用

函数是一段具有特定功能的、可重用的语句组,通过函数名来表示和调用。

函数的使用包括两部分:函数的定义和函数的使用

1、函数的定义

Python语言通过保留字def定义函数,语法形式如下:

def <函数名>(<参数列表>):
    <函数体>
    return <返回值列表>

函数名可以是任何有效的Python标识符,参数列表是调用该函数时传递给它的值,可以有零个、一个或多个,当传递多个参数由逗号分隔,当没有参数时也要保留圆括号。参数列表中的参数是形式参数,简称“形参” ,相当与实际参数的一种符号表示或符号占位符。

函数体是函数每次被调用时被执行的代码,由一行或多行语句组成。如果需要返回值,使用保留字return和返回值列表。函数可以没有return语句,函数体结束后会将控制权返回给调用者

例如,定义一个整数n的阶乘计算函数,代码如下:

def fact(n):
    s=1
    for i in range(1,n+1):
        s*=i
    return s

提示:无return函数

当函数没有return时,仅表示执行一段代码功能。

2、函数的使用

函数的定义也叫函数“声明”,定义后的函数不能直接运行,需要经过“调用”才能得到运行。

调用函数的基本方法如下:

<函数名>(<实际赋值参数列表>)

例如。定义一个整数n的阶乘计算函数,同时对其进行调用,代码如下。

#定义一个对整数n求阶乘的函数
def fact(n):
    s=1
    for i in range(1,n+1):
        s*=i
    return s
#调用整数阶乘函数
print(fact(100))
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000

每次调用函数可以提供不同参数作为输入,以实现对不同数据的处理;

函数执行后,可以反馈相应的处理结果。函数的执行与黑盒类似,使用者不需要了解函数内部实现原理,只要了解函数的输入输出方式即可。

具体来说,函数的使用一共分为4个步骤。

(1)函数定义

使用def保留字将一段代码定义为函数,需要确定函数名、参数名、参数的个数,使用参数名称作为形式参数(占位符)编写函数内部的功能代码。

(2)函数调用

通过函数名调用函数功能,对函数的各个参数赋予实际值,实际值可以是实际数据,也可以是在调用函数前已经定义过的变量。

(3)函数执行

函数被调用后,使用实际参数(赋予形式参数的实际值)参与函数内部代码的运行,如果有结果则进行输出。

(4)函数返回

函数执行结束后,根据return保留字的指示决定是否返回结果,如果返回结果,则结果将被放置到函数被调用的位置,函数使用完毕,程序继续运行。

编程中大量使用函数已经成为一种编程范式,叫作函数式编程。

在Python中,函数也是有类型的,可以通过type()获得函数类型。函数采用其定义的名字表达,具体为function类型,这是一种Python的内置类型。然而,如果调用函数,则类型为返回值的类型。

def f(x):
    return x+1

type(f)
<class 'function'>

type(f(1))
<class 'int'>

上述代码,函数f()是function类型,但其调用f(1)的类型是被调用函数返回值的类型,因为

f(1)返回数字为2,为整数类型,所以f(1)的类型是整数。

Python语言最小函数可以不表达任何功能,如下:

def f():
    pass

其中,保留字pass表示不进行任何操作,起到占位作用,因为函数体内部总要编写一行代码,pass用来表示这种占位。对f()的调用不实现任何功能。

二、函数的参数传递

1、可选参数传递

函数的参数在定义时可以指定默认值,当函数被调用时,如果没有传入对应的参数值,则使用函数定义时的默认值替代。带有可选参数的函数定义语法形式如下:

def <函数名>(<非可选参数列表>,<可选参数>=<默认值>):
    <函数体>
    return <返回值列表>

以两个数的乘法计算函数为例,设y为可选参数,示例如下。

def multiply(x,y=10):
    print(x*y)

    
multiply(99)
990

multiply(99,2)
198

需要注意,可选参数一般放置在非可选参数的后面,即定义函数时,先给出所有非可选参数,然后再分别列出每个可选参数及对应的默认值。

2、参数名称传递

函数调用时,默认采用按照位置顺序的方式传递给函数,例如multiply(99,2)中第一个实参默认赋值给形参x,第二个实参赋值给形参y。

Python语言同时支持函数按照参数名称方式传递参数,语法形式如下:

<函数名>(<参数名>=<实际值>)

以两个数的乘法计算函数为例,观察multiply()函数的调用方式,示例如下。

def multiply(x,y=10):
    print(x*y)

    
multiply(x=99)
990

multiply(y=2,x=99)
198

采用参数名称传递方式不需要保持参数传递的顺序,参数之间的顺序可以任意调整,只需要对每个必要参数赋予实际值即可,这种方式会显著增强程序的可读性。

3、函数的返回值

return语句用来结束函数并将程序返回到函数被调用的位置继续执行。return语句可以出现在函数中任何部分,同时可以将0个、1个或多个函数运算的结果返回给函数被调用处的变量。

以两个数的乘法计算函数为例,观察multiply()函数的返回值,示例如下。

def multiply(x,y=10):
    return x*y
s=multiply(99,2)
print(s)

198

提示:多个返回值

当return返回多个值时,这些值形成了一个元组数据类型,由小括号和逗号分隔,例如(a,b,c)。

元组是Python内置的一种组合数据类型。

以两个数的乘法计算函数为例,观察multiply()函数返回多个值的情况,示例如下。

def multiply(x,y=10):
    return x*y,x+y

s=multiply(99,2)
print(s)

(198, 101)

a,b=multiply(99,2)
print(a)

198

print(b)

101

当函数存在多种结束条件时,将使用多个return语句,例如:

def manyret(x):
    try:
        if x>0:
            return x+1
        else:
            return x-1
    except:
        return 0

在manyret()函数中由于存在try-except异常判断及if-else分支语句,该函数有3个出口,每个出口都有return语句,因此共有3个返回return语句。

三、变量的作用域

根据程序中变量所在的位置和作用范围,变量分为局部变量和全局变量。局部变量仅在函数内部使用,且作用域也在函数内部。全局变量可以跨越函数使用,作用域覆盖整个程序。

1、局部变量

局部变量是指函数内部定义并使用的变量,仅在函数内部有效,当函数退出时变量将不再存在。

以两个数的乘法计算函数为例,multiply()函数内部定义的变量z是局部变量,代码如下:

def multiply(x,y=10):
    z=x*y #z是函数内部的局部变量
    return z

s=multiply(99,2)
print(s)
198
print(z)
Traceback (most recent call last):
  File "<pyshell#45>", line 1, in <module>
    print(z)
NameError: name 'z' is not defined

当multiply()函数调用后,变量z将不存在,因此再使用这个变量会报错。

2、全局变量

全局变量指在函数之外定义的变量,在程序执行全过程有效。全局变量在函数内部使用时,需要提前使用保留字global声明,语法形式如下:

global<全局变量>

以两个数的乘法计算函数为例,观察multiply()函数中变量n及对变量n的声明,代码如下。

n=2 #n是全局变量
def multiply(x,y=10):
    global n
    return x*y*n #使用全局变量n

s=multiply(99,2)
print(s)
396

提示:全局变量声明

使用global对全局变量进行声明时,该变量要与外部全局变量同名。

上例中,变量n是全局变量,在函数multiply()中使用时需要在函数内部使用global声明,声明后即可使用。如果未使用保留字global声明,即使名称相同,也不是全局变量,对比代码如下。

n=2 #n是全局变量
def multiply(x,y=10):
    n=x*y
    return n #此处的n不是全局变量

s=multiply(99,2)
print(s)
198
print(n)
2

尽管multiply()中使用了变量n,但由于没有用global保留字声明,该变量仍然是局部变量。使用global保留字声明后,外部定义变量的作用域才能进入函数内部,这种声明不能省略。

四、代码复用

函数是程序的一种基本抽象方式,它将一系列代码组织起来通过命名供其他程序使用。函数封装的直接好处是代码复用,任何其他代码只要输入参数即可调用函数,从而避免相同功能代码在调用处重复编写。代码复用有另一个好处,当更新函数功能时,所有被调用处的功能都被更新。

程序由一系列代码组成,如果代码是顺序但无组织,不仅不利于阅读和理解,也很难进行升级和维护。当程序长度在百行以上,如果不划分模块,程序的可读性就已经很糟糕了。解决这一问题最好的方法是将一个程序分割成短小的程序段,每一段程序完成一个小的且特定的功能。利用函数将程序合理划分为多个功能模块,并基于模块设计程序是一种常用的程序设计方法,被称为“模块化设计”。

模块化设计指通过函数的封装功能将程序划分成主程序、子程序和子程序间关系的表达。模块化设计是使用函数设计程序的思考方法,以功能块为基本单位,一般有两个基本要求:

·紧耦合:尽可能合理划分功能块,功能块内部耦合紧密

·松耦合:模块间关系尽可能简单,功能块之间耦合度低

耦合性指程序结构中各模块之间相互关联的程度,它取决于各模块间接口的复杂程度和调用方式。耦合性是影响软件复杂程度和设计质量的一个重要因素。紧耦合指模块或系统间关系紧密,存在较多或复杂的相互调用。紧耦合的缺点在于更新一个模块可能导致其他模块变化,复用较困难。松耦合一般基于消息或协议实现,系统间交互简单。

提示:模块化

松耦合代表了模块化,从系统观念来看,松耦合是总体设计原则。

利用函数只是模块化设计的必要非充分条件,根据计算需求合理划分函数十分重要。一般来说,完成特定功能或经常复用的一组语句应该采用函数来封装,并尽可能减少函数间参数和返回值的数量。

五、函数递归

1、递归定义

函数是一种代码封装,能够被其他程序调用,当然,也可以被函数自身的内部代码调用。这种函数定义中调用函数自身的方式称为递归。

数学上一个经典的递归例子叫阶乘,其中,n的阶乘与n-1的阶乘有关,体现了递归关系。递归不是循环,因为每次递归都会计算比它更小数的阶乘,直到0!。0!是已知的值,被称为递归的基例。当递归到底了,就需要一个能直接算出值的表达式。

递归的两个关键特征

(1)递归基例:存在一个或多个基例,不需要再次递归,它是确定的表达式。

(2)递归链条:所有递归都有一个链条,表现为函数功能的不同值调用。

2、递归构建

以阶乘计算为例,可以把阶乘定义为一个单独的函数fact(n),表示n!.如下代码给出阶乘计算的代码实现。

def fact(n):
    if n==0:
        return 1
    else:
        return n*fact(n-1)
num=eval(input("请输入一个整数:"))
print(fact(abs(int(num))))
    

如第五行所示,fact()函数在其定义内部引用了自身,这就形成了递归过程。fact()函数通过if语句给出了n为0时的基例,当n==0,fact()函数不再递归,返回数值为1,如果n!=0,则通过递归返回n与n-1阶乘的乘积。

由于负数和小数通过减一无法到达递归基例(n==0),代码第七行通过abs()和int()函数将用户的输入转变为非负整数,该程序输出效果如下:

请输入一个整数:23
25852016738884976640000


请输入一个整数:-12
479001600

每次函数调用时,函数参数的副本会临时储存,递归中各函数再运算自己的参数,相互没有影响。当基例结束运算并返回值时,各函数逐层结束运算,向调用者返回计算结果。

递归可以解决很多计算问题。以字符串反转为例,对于用户输入的字符串s,输出反转后的字符串。基本思想是把字符串看作一个递归对象,长字符串由较短字符串组成,每个短字符串也是是一个对象。假如把一个字符串看成仅由两部分组成:首字符和剩余字符串。如果将剩余字符串与首字符交换,就完成了反转整个字符串,代码如下:

def reverse(s):
    if s=="":
        return s
    else:
        return reverse(s[1:])+s[0]
str=input("请输入一个字符串:")
print(reverse(str))

观察这个函数的工作过程。s[0]是首字符,s[1:]是剩余字符串,将它们反向连接,可以得到反转字符串。执行这个程序,结果如下:

请输入一个字符串:日照香炉生紫烟
烟紫生炉香照日

3、递归计算方法

递归是一种计算方法,如同数学归纳法。

证明一个与自然数相关的命题P(n)时,数学归纳法采用如下步骤。

(1)证明当n取第一个值n_{_{0}}时命题成立.

(2)假设当n_{k}时命题成立,证明当n=n_{k}+1时命题也成立。

综合(1)和(2),对一切自然数n(n>=n_{_{0}}),命题P(n)都成立。

递归和数学归纳法都利用了递归原理,本质相同。它们都由链条和基例构成,表达计算问题的解决路线,递归计算方式具体使用函数、分支等语法表达问题,进而利用计算机解决问题。需要注意,递归计算不需要直接给出求解公式,仅需要利用计算机程序表达问题即可,递归会利用计算机的强大算力展开链条,逐次计算得到结果。

六、过程式与函数式编程

编程方法是如何思考、设计、编写程序的方法,与编程语言的语法一样重要。介绍过程式编程和函数式编程两个方法。

过程式编程是一种以计算过程或运算流程为中心的编程方法,也是一种十分自然、符合人类思维方式的编程方法。面对一个计算任务,最直接的描述方式是按照操作流程或步骤进行分解,并编写代码逐步实现流程或步骤所要求的计算功能。过程式编程采用这种方式,以划分计算步骤为主要方法,组织程序代码。

Python语言通过编程语言支持过程式编程。一般来说,采用顺序、分支、循环等逻辑就可以完整描述计算过程。例如,将百分制成绩转化为五分制成绩,代码如下:

#将百分制成绩转换为五分制成绩
score=eval(input("请输入一个百分制成绩:"))
if score>=90.0:
    grade="A"
elif score>=80.0:
    grade="B"
elif score>=70.0:
    grade="C"
elif score>=60.0:
    grade="D"
else:
    grade="E"
print("对应的五分制成绩是:{}".format(grade))

过程式编程主要关注流程描述。用函数获取用户输入成绩,用分支判断成绩并进行相应转换,最后打印输出。只要将计算步骤梳理清楚,按照步骤编写程序即可。

函数式编程方法是过程式编程的一种演进,亦称模块化编程。函数式编程的主要思想是把程序过程尽量写成一系列函数调用,这能够使代码编写更简洁、更易于理解。函数式编程是软件项目中最常见的编程方式,也是代码复用的主要方式。

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

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

相关文章

判别分析2|Bayes判别分析|Fisher判别分析|软件求解

Bayes判别分析 引入先验信息 距离判别只要求知道总体的数字特征&#xff0c;不涉及总体的分布函数 当均值和协方差未知时&#xff0c;就用样本的均值和协方差矩阵做估计值。距离判别方法简单实用&#xff0c;但没有考虑到每个总体出现的机会大小&#xff0c;即先验概率&#…

数据结构(邓俊辉)学习笔记】优先级队列 09——左式堆:合并算法

文章目录 1. LeftHeap模板类2. 算法3. 实现4. 实例 1. LeftHeap模板类 接下来这节&#xff0c;来讨论左式堆的合并算法。再给出具体算法之前&#xff0c;首先要给出左式堆模板类的定义。 比如这就是一种可能的实现方式&#xff0c;可以看到&#xff0c;我们这里再次利用了 C…

srm供应商一体化招采系统解决方案,需求功能清单以及源码实现(JAVA)

1. 供应商管理 2. 采购需求管理 3. 采购寻源管理 4. 采购合同管理 5. 采购订单管理 6. 采购协同管理 7. 外部商城采购管理 8. 报表查询管理 9. 系统管理 10. 集成管理 资料获取&#xff1a;本文末个人名片。

在Activity中使用Menu

在Activity中使用Menu 手机毕竟和电脑不同&#xff0c;它的屏幕空间非常有限&#xff0c;因此充分地利用屏幕空间在手机界面设计中就显得非常重要了。如果你的活动中有大量的菜单需要显示&#xff0c;这个时候界面设计就会比较尴尬&#xff0c;因为仅这些菜单就可能占用屏幕将…

构建高效的串行任务执行器:SerialExecutor深度解析

本文主要介绍怎么去实现一个支持串行执行任务的SerialExecutor执行器 摘要 在复杂的异步编程中&#xff0c;有时我们需要确保任务以串行的方式执行&#xff0c;以维护任务间的依赖关系或顺序。SerialExecutor 是一个自定义的执行器&#xff0c;它封装了 Java 的 Executor 接口…

Linux磁盘分区,增加磁盘应用实例,磁盘情况查询

目录 linux磁盘分区机制 原理介绍 示意图 硬盘说明 查看所有设备挂载情况 挂载的经典案例 给虚拟机添加硬盘 分区 删除挂载 永久挂载 磁盘情况查询 查询系统整体磁盘使用情况 查询指定目录的磁盘占用情况 linux磁盘分区机制 原理介绍 载入可以将一个分区和一个目录…

【精选】基于微信小程序的地铁站点查询系统(全网独一无二,阿龙原创设计)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

C#入门篇3

目录 一、练习 二、显示类型转换&#xff08;强制类型转换&#xff09; 三、Convert的转换工厂转换 四、算数运算符号之&#xff08; /--&#xff09; 五、关系运算符&#xff08;比较运算&#xff09; 六、逻辑运算符 七、复合运算符 一、练习 计算半径为5的圆的面积和周…

Windows平台SDKMAN工具使用

为方便jvm生态的软件版本管理&#xff0c;可以使用sdkman工具来安装和管理诸如java、gradle等软件的当前使用版本。尤其是大多数程序员都是在windows平台开发&#xff0c;团队开发通常都需要统一的jvm相关软件的版本。这里给大家演示下windows平台如何安装和使用sdkman来实现这…

普元EOS-自定义SDO代码生成模板

1 前言 普元EOS的数据实体生成SDO接口和实现类的代码&#xff0c;可以通过自定义代码生成模板&#xff0c;实现代码自定义。 2 模板存放位置 模板存放位置如下&#xff1a;安装目录/dropins/eostools/com.primeton.studio.entity.ui-x.x.x.x.jar里面&#xff0c;SDO模版都在/…

揭秘CAAC、AOPA、ALPA、ASFC和UTC无人机执照的差别及实用价值

CAAC、AOPA、ALPA、ASFC和UTC无人机执照各有其独特的差别及实用价值&#xff0c;以下是针对这些执照的详细解析&#xff1a; 一、CAAC无人机执照 颁发机构&#xff1a;中国民用航空局&#xff08;CAAC&#xff09; 差别&#xff1a; - 权威性&#xff1a;CAAC无人机执照是目…

Go机器学习框架之火重燃,Google前研究员开源期望媲美Jax的GoMLX

Go作为一门兼具高性能与简洁性的编程语言&#xff0c;近年来在各种领域得到广泛应用。然而&#xff0c;在机器学习领域&#xff0c;Go相比Python、C、Julia等语言&#xff0c;生态仍然较为薄弱。目前的Go机器学习框架无论在功能全面性上&#xff0c;还是在社区生态支持上都难以…

2024升级zblog小程序开源源码/基于uniapp开发的(支持微信小程序、百度小程序、安卓APP)

源码简介&#xff1a; 2024最新zblog多端小程序开源源码&#xff0c;它是基于uniapp开发的&#xff0c;它是针对和支持微信小程序、百度小程序和安卓APP哦&#xff01;百度百科小程序源码下载。 这个基于uniapp开发的zblog多端小程序开源源码&#xff0c;听说对收录和SEO都有…

Android 添加系统服务的实现

和你一起终身学习&#xff0c;这里是程序员Android 本篇文章主要介绍 Android 开发中的部分知识点&#xff0c;通过阅读本篇文章&#xff0c;您将收获以下内容: 一、前言二、编写AIDL文件三、编写Manager类四、 编写系统服务五、 注册系统服务六、注册Manager七、App调用八、添…

设计模式 -- 七大原则(五)-- 开闭原则

1 基本介绍 开闭原则&#xff08;Open Closed Principle&#xff0c;简称OCP&#xff09;是编程中最基础、最重要的设计原则 一个软件实体如类&#xff0c;模块和函数应该对扩展开放(对提供方)&#xff0c;对修改关闭(对使用方)。用抽象构建框架&#xff0c;用实现扩展细节。 …

伯努利朴素贝叶斯解析:面向初学者的带代码示例的视觉指南

通过二进制简单性释放预测能力&#xff0c;欢迎来到雲闪世界。 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 与虚拟分类器的基线方法或基于相似性的 KNN 推理不同&#xff0c;朴素贝叶斯利用了概率论。它结合了每个“线索”&#xff08;或特征&#xf…

宿舍管理系统设计与分析

第一章 管理信息系统概述 在人类进入21世纪之际&#xff0c;随着社会的组织化程度以及企业生产的社会化程度越来越高&#xff0c;信息作为一种资源已经和材料、能源并称为现代社会化发展的三大支柱之一。管理信息系统是融科学、信息科学、系统工程以及现代通讯技术、计算机技术…

阿里HPN-大型语言模型训练的数据中心网络架构

阿里巴巴HPN:用于大型语言模型训练的数据中心网络 摘要 本文介绍了阿里云用于大型语言模型(LLM)训练的数据中心网络HPN。由于LLM和一般云计算之间的差异(例如&#xff0c;在流量模式和容错性方面)&#xff0c;传统的数据中心网络不太适合LLM训练。这就要求我们专门为LLM培训设…

【NetTopologySuite类库】多边形的五种包围盒(AABB、OBB、包围圆、八边形、凸包)

示例 用的是NetTopologySuite1.5.3版本。 var r new WKTReader(); var wkt "polygon((0 0,0 0.5,1 2,5 0,4 -2,3 -1, 0 0))"; var rawGeo r.Read(wkt); var b1 rawGeo.Envelope;//AABB var b2 new MinimumBoundingCircle(rawGeo).GetCircle();//包围圆 var b3…

基于GeoToolKit实现三维断面的绘制研究

GeoToolkit默认自带PillarSurfaceData的三维断面绘制要求断棱(有时叫断柱)必须是单调的,否则组件底层就会自动优化,导致断面出现回弯,相当于出现重叠,无法实现最终的效果。因此,本文主要在之前文章的基础上,拓展了GeoToolKit的三维断面显示功能。本文主要基于GeoToolKi…