python编程语言之函数基础

函数基础

设计一个程序输出一下图案效果:

     *************************
*************************************************************
************************************

根据已经学过的内容,我们的实现方式如下:

rows=6#第1个菱形的上半部分
for i in range(rows):for j in range(rows-i):print(" ",end=" ")j+=1for k in range(2*i-1):print("*",end=" ")k+=1print("\n")#第1个菱形的下半部分
for i in range(rows):for j in range(i):print(" ",end=" ")j+=1for k in range(2*(rows-i)-1):print("*",end=" ")k+=1print("\n")rows=6
#第2个菱形的上半部分
for i in range(rows):for j in range(rows-i):print(" ",end=" ")j+=1for k in range(2*i-1):print("*",end=" ")k+=1print("\n")#第2个菱形的下半部分
for i in range(rows):for j in range(i):print(" ",end=" ")j+=1for k in range(2*(rows-i)-1):print("*",end=" ")k+=1print("\n")

相信大家一定看出来了,这种方式会出现大量重复代码,对于阅读和维护整个程序都会变得十分麻烦。

这时候,函数就出现了!

简单说,函数就是一段封装好的,可以重复使用的代码,它使得我们的程序更加模块化(让代码关联起来形成一个整体),避免大量重复的代码。

刚才的程序函数版本:

def print_ling():"""输出菱形图案"""rows=6i=j=k=1#菱形的上半部分for i in range(rows):for j in range(rows-i):print(" ",end=" ")j+=1for k in range(2*i-1):print("*",end=" ")k+=1print("\n")#菱形的下半部分for i in range(rows):for j in range(i):print(" ",end=" ")j+=1for k in range(2*(rows-i)-1):print("*",end=" ")k+=1print("\n")print_ling()
print_ling()

如果在开发程序时,需要某一段代码多次使用,但是为了提高编写的效率以及代码的重用,所以把具有独立功能的代码块组织为一个小代码块,这就是函数(function)。

函数声明

声明一个函数,也就是创建一个函数,可以理解为将一段可以重复使用的代码通过关键字def包裹起来。具体的语法格式如下:

'''
def 函数名(参数列表):'''# 函数说明文档,告诉别人这个函数的作用params: 参数return: 结果'''# 实现特定功能的多行代码[return [返回值]]
'''

定义了函数之后,就相当于有了一个具有某些功能的代码。函数的声明并没有执行函数中的代码块,想要执行函数体,需要进行函数调用,一个函数可以调用多次。函数调用语法:

# 定义完函数后,函数是不会自动执行的,需要调用它才可以
函数名()

每次调用函数时,函数都会从头开始执行,当这个函数中的代码执行到最后或者遇到关键字return时,意味着调用结束了。

def foo():print("foo函数")# 要调用一个函数,这个函数必须先声明好了。
foo()

debug模式运行:

# 一个程序总,可以定义多个不同的函数,每一个函数都可以反复多次# 函数的声明
def bar():print("bar1")print("bar2")print("bar3")# 函数的声明
def foo():print("foo1")print("foo2")print("foo3")# 函数调用,一个函数可以调用多次,每次都是从第一行开始执行
foo()
# 函数调用
bar()
# 函数调用
foo()

函数的文档说明

在工作中,我们经常会需要根据各种不同的情况对代码进行封装成各种不同功能的函数,有时候函数多了,或者函数的代码多了,这时候,会让人一下子记不起来或者看不明白这个函数有什么作用,所以我们可以使用函数的文档说明,来提示使用者,当前函数的用法或者效果。

def triangle():"打印一个5行的三角形图案"line = 5for i in range(line):print(" " * (line - i), end="")print("*" * (i * 2 + 1))# 通过help可以看到函数的文档信息
help(triangle)
# Help on function triangle in module __main__:
#
# triangle()
#     打印一个5行的三角形图案print(triangle.__doc__)
# 打印一个5行的三角形图案

针对函数的使用,如果我们使用的编辑器是ide工具,一般都会对函数本身使用说明文档,进行提示:

针对函数的使用,如果我们使用的编辑器是ide工具,一般都会对函数本身使用说明文档,进行提示:
1. 我们可以通过鼠标悬放在函数名上方就可以看到函数的说明文档了。
2. 我们还可以通过Ctrl+鼠标左键,就可以直接跳转到函数声明位置(有可能是当前文件,也可能是python内置的python文件位置)。
3. 当我们如果跳转到了其他文件,希望能快速返回之前的鼠标点击位置,可以使用alt+方向键(← 和 →)如果同一个文件下,继续使用Ctrl+鼠标左键

如果我们使用的不是IDE工具,但是又想要了解函数的声明文档,可以使用以下2种方式:

# 1. 使用help函数打印指定函数的使用文档。
help(函数名) # 2. 通过print打印指定函数的__doc__属性
print(函数名.__doc__)

函数参数

声明一个计算1-100和的函数

def cal_sum():ret = 0for i in range(1,101):ret+=iprint(ret)

像上面我们举的例子,如果我想计算1-200的和怎么弄?再声明一个新的函数吗?

我们会发现计算1-100和与计算1-200的和的步骤是相同的,只有需要改变range()的第二个选项参数。

def cal_sum():ret = 0num = 101 # 放在函数里面for i in range(1, num):ret+=iprint(ret)cal_sum()
cal_sum() # 这里还是只能计算1-100之间的和。

如果我们把num变量放到外面呢?

max_num = 101 # 放在函数外面
def cal_sum():ret = 0# num = 101 # 放在函数里面for i in range(1, max_num):ret+=iprint(ret)cal_sum() # 5050
max_num = 201
cal_sum() # 20100

我们可以发现,把num放在函数外面以后,cal_sum更强大了,可以1-100或者1-任何数字之间的和了。但是这样的代码,没办法让人清晰的知道max_num和cal_sum是一块的。所以,如果这个函数提供给其他人员使用,其他人员可能都不知道有这个变量。

形参和实参

函数的参数可以解决上面的问题,函数的函数可以使函数的功能更加强大,让函数变得更加灵活:

# 案例1
def cal_sum(temp):  # temp就是引入的函数形式参数ret = 0for i in range(1,temp+1):ret+=iprint(ret)cal_sum(100)   # 每次调用可以根据需要传入需要的值,这个具体的值成为实际参数简称实参。
cal_sum(101)   # 案例2
def add():x = 10y = 20print(x+y)def add(x, y):  # 声明的参数称之为形式参数,简称形参print(x + y)# 调用add函数 # 将调用过程中传入的值称之为实际参数,简称实参
add(5, 6)  # 将5赋值给x,将6赋值给了y ,函数体将x+y,即5+6计算出来,打印
# 调用add函数
add(10, 5)  # 将10赋值给x,将6赋值给了5 ,函数体将x+y,即10+5计算出来,打印

代码执行过程:https://pythontutor.com/live.html#mode=edit

在函数的定义阶段 括号内写的变量名,叫做该函数的形式参数,简称形参。在函数的调用阶段,括号内实际传入的值,叫做实际参数,简称实参。该例中,temp就是的函数形式参数,而每次调用根据需要传入的值,比如100,101都是实参。

形参就相当于变量名,而实参就相当于变量的值,函数调用传参的过程 就是给形参变量名赋值的过程。

函数参数只有在函数调用阶段有效,函数运行结束,参数作为垃圾被内存释放(也就是删除)。

位置参数

位置参数,有时也称必备参数,指的是必须按照正确的顺序将实际参数传到函数中,换句话说,调用函数时传入实际参数的数量和位置都必须和定义函数时保持一致。

# 例1
def add(x,y): # x,y是形参,用来接收实参print(x+y)add(2,3) # 2,3 是实际参数,分别传递给形参x,y# 例2
def add(x,y,z): print(x+y)add(2,3) # 缺少一个实际参数传递给z# 例3
def add(x,y):print(x+y)add(2,3,4) # 缺少一个形式参数接收给z

默认参数

Python 允许为参数设置默认值,即在定义函数时,直接给形式参数指定一个默认值。这样的话,即便调用函数时没有给拥有默认值的形参传递参数,该参数可以直接使用定义函数时设置的默认值。

def print_stu_info(name,age,gender="male"):print("学员姓名:",name)print("学员年龄:",age)print("学员性别:",gender)print_stu_info("张三",23)

当定义一个有默认值参数的函数时,有默认值的参数必须位于所有没默认值参数的后面,否则报错!

关键字参数

关键字参数可以避免牢记参数位置的麻烦,令函数的调用和参数传递更加灵活方便。关键字参数是指使用形式参数的名字来确定输入的参数值。通过此方式指定函数实参时,不再需要与形参的位置完全一致,只要将参数名写正确即可。

def print_stu_info(name,age,height,weight,job):print("学员姓名:",name)print("学员年龄:",age)print("学员身高:",height)print("学员体重:",weight)print("学员工作:",job)print_stu_info("张三",23,"180cm","80kg","销售")
print_stu_info(name="张三",height="180cm",weight="90kg",job="销售",age=23)
print_stu_info("张三",height="180cm",weight="90kg",job="销售",age=23)

使用位置参数和关键字参数混合传参的方式。但需要注意,混合传参时关键字参数必须位于所有的位置参数之后。

不定长参数

在函数定义中使用*args**kwargs传递可变长参数。*args用作传递非命名键值可变长参数列表(位置参数);**kwargs用作传递键值可变长参数列表。*args 的参数会以元组(tuple)的形式导入,存放所有未命名的变量参数。**kwargs的参数会以字典的形式导入。

不定长参数也叫收集参数。

# *args
def add(*args):print(args)print(type(args))ret = 0for i in args:ret += iprint(ret)add(12,23,45)# **kwargs
def print_stu_info(**kwargs,):print(kwargs)print_stu_info(name="张三",height=190)

同时使用*args**kwargs:

def print_stu_info(name, age=18, *args, **kwargs):print(name, age)print(args)print(kwargs)print_stu_info("yuan", 20, "China", "Beijing", height="188cm", weight="60kg")

注意点:

1、参数arg*args**kwargs三个参数的位置必须是一定的。必须是(arg,*args,**kwargs)这个顺序,否则程序会报错。

2、不定长参数的长度可以为零。

3、argskwargs其实只是编程人员约定的变量名字,args 是 arguments 的缩写,表示位置参数;kwargs 是 keyword arguments 的缩写,表示关键字参数。

函数返回值

到目前为止,我们创建的函数都只是对传入的数据进行了处理,处理完了就结束。但实际上,在更多场景中,我们还需函数将处理的结果反馈回来。通过关键字return语句可以返回任意类型的数值。

基本使用

def add(x,y):return  x+y # return是函数的终止语句
ret = add(2,3)
print(ret)

默认返回值

在 Python 中,有一个特殊的常量 None(N 必须大写)。和 False 不同,它不表示 0,也不表示空字符串,而表示没有值,也就是空值。None 是 NoneType数据类型的唯一值(其他编程语言可能称这个值为 null、nil 或 undefined),也就是说,我们不能再创建其它 NoneType类型的变量,但是可以将 None 赋值给任何变量。

Python一个函数中如果没有return语句或者return后没有具体值,都默认返回None,比如print()函数就没有返回。

返回多个值

return也可以返回多个值,python其实会将多个值放在一个元组中元组返回。

def login(user,pwd):flag = Falseif user == 'yuan' and pwd == 123:flag = Truereturn flag,user# ret = login("yuan",123)
flag,user = login("yuan",123)if flag:print("{}登陆成功!".format(user))
else:print("用户名或者密码错误!")

函数嵌套

def foo():def bar():print("bar功能")print("foo功能")bar()foo()
# bar() 嵌套函数无法在外界使用。

作用域

所谓作用域(Scope),就是变量的有效范围,就是变量可以在哪个范围以内使用。有些变量可以在整段代码的任意位置使用,有些变量只能在函数内部使用。

LEGB

字母英语释义简称作用空间
LLocal(function)当前函数内的作用域局部作用域局部
EEnclosing Functions Locals外部嵌套函数的作用域嵌套作用域局部
GGlobal(module)函数外部所在的命名空间全局作用域全局
BBuilt In(python)Python内置模块的命名空间内建作用域内置

因为作用域的问题,所以按不同作用域可以把变量划分为2种:局部变量与全局变量。

  • 局部变量,函数内部声明的变量。默认情况下,只有在函数运行时局部变量才会出现在内存中,当函数执行结束,内存中的局部变量就会被销毁,所以局部变量无法被当前函数以外的地方使用。
  • 全局变量,函数外部声明的变量,或者在函数内部显式声明为全局变量。默认在任意位置都可以使用,从被声明的位置开始,直到程序结束或者被del关键字删除。
# 案例1def foo():x = 10foo()
print(x)# 案例2x = 100
def foo():x = 10
foo()
print(x)# 案例3x = 100
def foo():x = 10print(x)
foo()
print(x)# 案例4x = 100
def foo():print(x)
foo()# 案例5
x = 100
def foo():x = 12def bar():x = 1print(x)bar()
foo()

global

count = 1def a():count = 'a函数里面'def b():global count  # 告诉python,当前函数中使用的count,是顶级作用域的print(count)count = 2b()print(count)a()
print(count)

nonlocal

count = 1def a():count = 'a函数里面'def b():nonlocal count  # 告诉python,当前函数中使用的count,不是b作用域的而是,外部作用域的print(count)count = 2b()print(count)a()
print(count)

匿名函数

lambda 表达式,又称匿名函数,常用来表示内部仅包含 1 行表达式的函数。如果一个函数的函数体仅有 1 行表达式,则该函数就可以用 lambda 表达式来代替。

lambda 表达式的语法格式如下:

# name = lambda [list] : 表达式

其中,定义 lambda 表达式,必须使用 lambda 关键字;[list] 作为可选参数,等同于定义函数是指定的参数列表;value 为该表达式的名称。

def add(x, y):return x+ y
print(add(2,3))(lambda x,y:x+y)(2,3)

可以这样理解 lambda 表达式,其就是简单函数(函数体仅是单行的表达式)的简写版本。相比函数,lambda 表达式具有以下 2 个优势:

  • 对于单行函数,使用 lambda 表达式可以省去定义函数的过程,让代码更加简洁;
  • 对于不需要多次复用的函数,使用 lambda 表达式可以在用完之后立即释放,提高程序执行的性能。
list = [1, "2", "C", "D", "A"]
# list.sort() # 会报错,因为列表中的成员类型不一样。list = [1, "2", "C", "D", "A"]
# list.sort()list.sort(key= lambda x: str(x))
print(list)

函数名的使用

python中函数与其他数据类型一样同属于一等公民(first-class elements,也叫一等对象)。

Elements with the fewest restrictions are said to have first-class status. Some of the ''rights and privileges'' of first-class elements are:1. They may be named by variables.2. They may be passed as arguments to procedures.3. They may be returned as the results of procedures.4. They may be included in data structure总而言之,就是你能把函数像普通变量一样任意地使用。包括赋值给变量以及作为其它函数的参数和返回值。
所以,所谓的“一等公民”是指代满足下述条件的程序实体:
1、可赋值给变量,让变量代表它运行。
2、可作为函数的参数。
3、可作为函数结果返回。
4、可包含在数据结构中,例如可以包含在列表等数据类型中作为成员存在。因此,整数、浮点数、字符串、列表、字典、元组、函数、类本身、类型本身以及模块等都是对象。
因为都是对象,所以 Python 中的函数才和整数、字符串、列表、字典和元组等对象的地位是平等的,成为了“一等公民”。
def add(x, y):return x + ydef sub(x, y):return x - ydef div(x, y):return x / ydef mul(x, y):return x * ydef calc(x, y, func):return func(x, y)ret = calc(10, 20, add)
print(ret)ret = calc(10, 20, sub)
print(ret)

关于函数基础部分的内容全部都是重点。

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

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

相关文章

采集传感器的物联网网关怎么采集数据?

随着工业4.0和智能制造的快速发展,物联网(IoT)技术的应用越来越广泛,传感器在整个物联网系统中使用非常普遍,如温度传感器、湿度传感器、光照传感器等,对于大部分物联网应用来说,采集传感器都非…

Ubuntu学习笔记(二)——文件属性与权限

文章目录 前言一、用户与用户组1.用户(文件拥有者)2.用户组3.其他人 二、Linux用户身份与用户组记录文件1. /etc/passwd2. /etc/shadow3. /etc/group 三、文件属性与权限1. 查看文件属性的方法(ls)2.文件属性详细介绍2.1 权限2.2 …

将composer的bin目录放到PATH环境变量中

使用composer global config bin-dir --absolute查看composer的bin目录 输出类似 Changed current directory to /home/lijun/.config/composer /home/lijun/.config/composer/vendor/bin/home/lijun/.config/composer/vendor/bin就是composer的bin目录 将/home/lijun/.confi…

使用python里的神经网络进行数据分类预测

在Python中使用神经网络进行数据分类预测,可以使用深度学习库如TensorFlow、Keras或PyTorch来实现。以下是使用Keras库的示例代码: Step 1: 准备数据 首先,准备用于训练和测试神经网络的数据集。将数据集分为输入特征和相应的目标类别。确保…

MacOS触控板缩放暂时失灵问题解决

我的系统版本为Monterey 12.5.1,亲测有效 直接创建脚本xxx.sh,并在终端执行脚本bash xxx.sh即可解决此问题,脚本内容如下: #!/bin/bashkillall Finder #kill Finder如不需要可以删除 killall Dock #kill Dock 如不需要可以删…

【wxWidgets】使用布局控件进行窗口布局

使用布局控件进行窗口布局 窗口布局基础 为了在各种环境中都能使窗口拥有合适的位置和大小,可能需要在OnSize事件中计算每一个窗口的大小并设置新位置,当然使用窗口布局控件可以更方便地实现 如果选择使用布局控件,可以通过自己编写或者使用…

【汉诺塔问题分析】

一、背景 汉诺塔问题是一种经典的递归问题,它由法国数学家Huygens在1665年发现,也是一道有趣的数学难题。这道问题的主要目的是将三根柱子上的一堆盘子移动到另一根柱子上,移动过程中每次只能移动一个盘子,并且大盘子不能放在小盘…

[QT编程系列-10]:C++图形用户界面编程,QT框架快速入门培训 - 4- QT画图与动画

目录 4. QT画图与动画 4.1 QT的绘图系统 4.2 案例目标 4.3 绘制过程 4.4 更换控件的icon 4.5 案例2 4.6 坐标轴 4. QT画图与动画 4.1 QT的绘图系统 QT(也称为Qt Framework)是一种流行的跨平台应用程序开发框架,它提供了丰富的图形用户…

集群基础1——集群概念、LVS负载均衡

文章目录 一、基本了解二、LVS负载均衡2.1 基本了解2.2 工作模式2.2.1 NAT模式2.2.2 DR模式2.2.3 LVS-TUN模式2.2.4 LVS-FULLNAT模式 三、调度器算法四、ipvsadm命令 一、基本了解 什么是集群? 多台服务器做同一件事情。 集群扩展方式: scale up&#xf…

2023年7月北京/广州/深圳制造业产品经理NPDP认证招生

产品经理国际资格认证NPDP是新产品开发方面的认证,集理论、方法与实践为一体的全方位的知识体系,为公司组织层级进行规划、决策、执行提供良好的方法体系支撑。 【认证机构】 产品开发与管理协会(PDMA)成立于1979年,是…

C# 移除链表元素

203 移除链表元素 给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val val 的节点,并返回 新的头节点 。 示例 1: 输入:head [1,2,6,3,4,5,6], val 6 输出:[1,2,3,4,5] 示例 2&#x…

PostgreSQL

一、基本使用 1. 交互式终端psql 连接至数据库&#xff1a; psql -h <ip地址> -p <端口号>\d&#xff1a;查看所有表\d 表名&#xff1a;查看表结构\timing&#xff1a;显示SQL语句执行时间 2. 表空间的使用 如果需要把不同的表放在不同的存储介质或不同的文件…

2023-07-14:讲一讲Kafka与RocketMQ中存储设计的异同?

2023-07-14&#xff1a;讲一讲Kafka与RocketMQ中存储设计的异同&#xff1f; 答案2023-07-14&#xff1a; 在Kafka中&#xff0c;文件的布局采用了Topic/Partition的方式&#xff0c;每个分区对应一个物理文件夹&#xff0c;且在分区文件级别上实现了顺序写入。然而&#xff0…

WIN无法访问linux开启的SAMBA服务器

WIN无法访问linux开启的SAMBA服务器 打开搜索框“管理Windows凭据” 点击编辑

TCP/IP网络编程 第十七章:优于select的epoll

epoll理解及应用 select复用方法其实由来已久&#xff0c;因此&#xff0c;利用该技术后&#xff0c;无论如何优化程序性能也无法同时接入上百个客户端&#xff08;当然&#xff0c;硬件性能不同&#xff0c;差别也很大)。这种select方式并不适合以Web服务器端开发为主流的现代…

Camtasia Studio 2023保存为mp4格式的视频的详细教程,Camtasia的视频导出功能

很多用户刚接触Camtasia Studio&#xff0c;不熟悉如何保存mp4格式的视频。在今天的文章中小编为大家带来了Camtasia Studio 2023保存为mp4格式的视频的详细教程介绍。 1、 打开Camtasia Studio。 Camtasia Studio- 2023 win&#xff1a; https://souurl.cn/1JFEsn Camtasia …

06_本地方法接口+07_本地方法栈

一、本地方法&#xff1f; 本地方法就是Java调用非Java代码的接口。 本地方法的作用是融合不同的编程语言为Java所用&#xff0c;它的初衷是融合 C、C程序 二、为什么要使用Native Method? 三、本地方法栈 Java虚拟机栈用于管理Java方法的调用&#xff0c;而本地方法栈用于…

【Linux】Docker 基本管理

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 Docker 基本管理 Docker 概述Docker 核心概念Docker 安装部署Docker 镜像操作Docker 容器操作 Docker 概述 Docker是一个开源的应用容器引擎&#xff0c;基于go语言开发并遵…

python爬虫中通用的两种乱码解决方式(自用)

问题&#xff1a;在python爬虫爬取的时候&#xff0c;我们有时会遇到诸如以下的乱码&#xff1a; &#xfffd;װŮ&#xfffd;&#xfffd; &#xfffd;&#xfffd;Ů ˮ СϪ Ψ&#xfffd;&#xfffd;¡4k解决方法一&#xff1a;用utf-8来转码&#xff0c;具…

spring复习:(40)全注解的spring AOP

零、需要的依赖&#xff1a; <dependency><groupId>org.aspectj</groupId><artifactId>aspectjrt</artifactId><version>1.8.9</version></dependency><dependency><groupId>org.aspectj</groupId><arti…