一、为什么需要函数

有没有发现,在前面的那么多的教程当中,我们没有函数是不是也是可以写的出来的,似乎没有函数这个东西,我们变成也是可以实现的,但是,在实际的开发过程中,我们为什么需要函数呢,它到底能够给我们变成带来怎样的好处呢?

其实,函数这个东西我们可以把它想成是一个包装盒,我们没有包装盒的时候,其实也是可以把礼物送给相送的人手上的,但是,当我们用包装盒包装美化之后,我们首先会更好拿,其次,会更加的好看,更赏心悦目,当然,我们要达到的目的就是,让收到礼物的人开心,所以,我们买礼物的时候,通常都会很用心的买一个包装盒美美的包装一下。

函数,就是这么个作用,我们需要把我们写的零零散散的代码包装起来,让它更好阅读,同时也能更好的管理我们的代码。

说了这么多,那么到底如何使用函数呢?下面一一道来。

二、如何定义函数

这里,我们先把上面用很浅显的话说的函数更加正式的表达一下。函数组织好的、可重复使用的、用户实现单一或者关联功能的代码段。函数能够提高应用的模块性和代码的重复利用率。

定义函数规则

def 函数名([参数列表]):      #参数列表可选项函数体

举例

def printName():print('我是 hello world!')printName()

注意几点

  • 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号()
  • 任何传入参数和自变量必须放在圆括号中间。
  • 函数内容以冒号起始,并且缩进。

是不是很简单,只要你学过一门编程语言,这些应该都是不值得一提。

现在我们定义好了函数,就相当于我们已经有了包装礼物的包装盒,那么我们如何用包装盒去包装礼物呢,也就是说我们如何去使用函数呢?

使用函数

规则

函数名([参数列表])

举例

  • 定义函数
def printName():print('我是 hello world!')
  • 调用函数
printName()

其实就是这么简单!

好了,在我们包装礼物的时候,可能我们会想收礼物的人写封信或者写点东西递交给他,这个时候,我们可能会写个小纸条啦,而函数,我们也可以传信哦!

这时候,就要用到函数参数这个概念了。

三、函数参数

函数参数就是说我们可以在定义函数的时候,在括号中定义变量,用于传给函数内部使用,已达到“传信”’的效果!

举例

def printName(name):print('我是:', name)

这个括号中的 name ,就是我们定义的函数参数了。

除了需要知道这个以外,我们还需要了解一个概念

实参与形参

那么什么是实参,什么是形参呢,通过下面这张图,你就知道了!

我们传信给对方的时候是不是也有很多的方式,比如,我们可以简单的拿张小纸条写写,也可以买个信封写封信。

同样,函数的参数也有一些不同的类型。

参数类型

位置实参

位置实参:函数定义中允许拥有多个形参,因此函数在调用的时候,也可能包含多个实参。向函数传递参数的方式有很多,通过实参和形参的顺序对应

关键字参数

关键字实参是传递给函数的名称-值对。直接在实参中将名称和值关联起来,因此向函数传递实参时不会混淆。函数调用使用关键字参数来确定传入的值。所以,位置可以不用对应。

# 定义函数
def printName(name, age):print('我是:', name)print('我:', age)# 调用函数
printName(age=18, name='欧阳思海') # 名字跟形参对应,但是位置可以不对应
参数默认值

在很多语言都是有默认值这个特性的。

**默认值:**函数定义的时候,设置的参数是形参。那么也可以给每个形参指定一个默认值。当调用函数时,如果没有传入实参,就使用形参的默认值。如果调用的时候传入了实参,那么程序将使用传入的实参。

# 定义函数:使用默认值 age=15
def printName(name, age=15):print('我是:', name)print('我:', age)# 调用函数
printName(age=18, name='欧阳思海')  # 名字跟形参对应,但是位置可以不对应
printName(name='欧阳思海')  # age有默认值,不赋值,默认15

不定长参数

**不定长参数:**你可能需要一个函数能处理比当初声明时更多的参数。

规则

def 函数名(*parameter,**parameter):函数体

**注意:**加了***的就是不定长参数。

# 定义函数
def printPara(*para, **para2):print(para)print(para2)# 调用函数
printPara('one', 'two', 'three', four='4', five='5')

由此可知:

  • 一个*的不定长参数,会接收没有命名的实参,且会转为元祖tuple
  • 两个*的不定长参数,会接受有命名的实参,且转化为字典dictionary

以上就是函数参数的内容了。

有时候,我们把信封放在礼物中送给对方之后,可能,她直接把礼物加信息拒绝了,这时候,就返回给你了。所以,把函数参数传过去之后,并不是一定就输出结果的,有时候,还会返回。所以就有返回值

四、函数返回值

换专业点的话说:函数其实并非我们想象的总是简单的将结果直接输出,相反,函数的调用者需要函数提供一些通过函数处理过后的一个或者一组数据,只有调用者拥有了这个数据,才能够做一些其他的操作。那么这个时候,就需要函数返回给调用者数据,这个就被称之为返回值,想要在函数中把结果返回给调用者,需要在函数中使用returnreturn 就是返回值的关键词

下面,我们用一个例子直接看 return 怎么使用。

def sum(a, b):return a + bresult = sum(1, 2)
print(result)

通过这个例子我们可以看出,通过 return 语句 这样的方式,就可以把 我们想要返回的东西返回。

然后,通过 调用函数 可以用一个变量 接收函数返回的值,以便保存使用。

看了这个例子之后,我想,我们应该知道 return 有什么作用了。

return 作用

  1. 返回结果。
  2. 退出函数,return 语句后的函数内容将不会再执行。

五、局部变量和全局变量

在编程语言中,都有叫做变量域的东西。也就是,限制我们变量在哪个地方能用,哪个地方不能用。

变量分为局部变量全局变量

局部变量:在函数内定义的变量,局部变量只能在所定义的函数内使用,在不同函数内定义的相同的变量是不会相互影响的,如果在函数 A 中定义了变量 variable,在函数 B 中也定义了变量 variable,这两个是相互不影响的。
全局变量:在函数外定义的变量,任何地方都可以使用。

举例

c = 3  # 全局变量def sum(a, b):d = 5  # 局部变量return a + bresult = sum(1, 2)
print(result)
print(c)  # 正确,全局变量处处可以访问
print(d)  # 错误,不能访问局部变量

下面,我们需要注意一个问题,当我们需要在函数内部修改一个全局变量时,我们需要用一个关键词 global 来声明,这样我们才能够改变。

举例

c = 3  # 全局变量
print('全局变量id:', id(c))def sum(a, b):global cc = 5  # 局部变量print('sum中全局变量id:', id(c))return a + bdef sum2(a, b):print('sum2中全局变量id:', id(c))return a + bsum(1, 2)
print('全局变量id..:', id(c))
sum2(2, 2)

在这个例子中我们可以看到,当我们用 global c 声明之后,后面再使用变量 c 的时候,变量 c 已经改变了。

再用一个例子,当我们不用 global 声明直接修改时,后面的 变量 c 的 id的值是不会改变了。

c = 3  # 全局变量
print('全局变量id:', id(c))def sum(a, b):# global cc = 5  # 局部变量print('sum中全局变量id:', id(c))return a + bdef sum2(a, b):print('sum2中全局变量id:', id(c))# c = 10return a + bsum(1, 2)
print('全局变量id..:', id(c))
sum2(2, 2)

注:id 是用来展示变量唯一性的。

六、匿名函数

**匿名函数:**定义函数的过程中,没有给定名称的函数就叫做 匿名函数;Python 中使用 lambda 表达式来创建匿名函数。

规则

lambda 参数列表: 表达式

下面我们先用一个例子来看看 lambda表达式 怎么使用。

举例

res = lambda a, b: a + bprint(res(1, 2)) # 输出3

其中,a,b是参数,a + b 是执行表达式,可以是简单的表达式,也可以是函数等。

def sum(a, b):return a + bres = lambda a, b: sum(a, b) #执行表达式是函数print(res(1, 2))

在前面的我们已经学过 if-else 形式了,在这里,再学习一种不一样的形式。

条件成立的内容   if 条件 else 条件不成立的内容

举例

s = lambda x, y: x if x > 2 else y
print(s(2, 4)) # 输出4

七、递归函数

递归就是子程序(或函数)直接调用自己或通过一系列调用语句间接调用自己。

形象点说就是一个黑洞一样,一层一层的往里走,走到最后,再往回走,直到走到出发点,这就是递归的整个过程。在走的过程中,我们就可以计算。

这里只是简单的说说递归函数的简单的用法。

例如:

阶乘 1 * 2 * 3 ··· * n

'''阶乘
'''
def jiechen(n):if n == 1:return 1else:return n*jiechen(n-1)print(jiechen(10))

这个例子,就是函数自己再调用函数自己。

八、高阶函数

map()函数接收两个参数,一个是函数,一个是序列,map将传入的函数依次作用到序列的每个元素,并把结果作为新的list返回。

举例说明,比如我们有一个函数f(x)=x2,要把这个函数作用在一个list [1, 2, 3, 4, 5, 6, 7, 8, 9]上,就可以用map()实现如下:

现在,我们用Python代码实现:

>>> def f(x):
...     return x * x
...
>>> map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
[1, 4, 9, 16, 25, 36, 49, 64, 81]

请注意我们定义的函数f。当我们写f时,指的是函数对象本身,当我们写f(1)时,指的是调用f函数,并传入参数1,期待返回结果1。

因此,map()传入的第一个参数是f,即函数对象本身。

map()函数这种能够接收函数作为参数的函数,称之为高阶函数(Higher-order function)。

你可能会想,不需要map()函数,写一个循环,也可以计算出结果:

L = []
for n in [1, 2, 3, 4, 5, 6, 7, 8, 9]:L.append(f(n))
print L

的确可以,但是,从上面的循环代码,能一眼看明白“把f(x)作用在list的每一个元素并把结果生成一个新的list”吗?

所以,map()作为高阶函数,事实上它把运算规则抽象了,因此,我们不但可以计算简单的f(x)=x2,还可以计算任意复杂的函数。

再看reduce的用法。reduce把一个函数作用在一个序列[x1, x2, x3…]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:

reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)

比方说对一个序列求和,就可以用reduce实现:

>>> def add(x, y):
...     return x + y
...
>>> reduce(add, [1, 3, 5, 7, 9])
25

当然求和运算可以直接用Python内建函数sum(),没必要动用reduce。

但是如果要把序列[1, 3, 5, 7, 9]变换成整数13579,reduce就可以派上用场:

>>> def fn(x, y):
...     return x * 10 + y
...
>>> reduce(fn, [1, 3, 5, 7, 9])
13579

这个例子本身没多大用处,但是,如果考虑到字符串str也是一个序列,对上面的例子稍加改动,配合map(),我们就可以写出把str转换为int的函数:

>>> def fn(x, y):
...     return x * 10 + y
...
>>> def char2num(s):
...     return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]
...
>>> reduce(fn, map(char2num, '13579'))
13579

整理成一个str2int的函数就是:

def str2int(s):def fn(x, y):return x * 10 + ydef char2num(s):return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]return reduce(fn, map(char2num, s))

还可以用lambda函数进一步简化成:

def char2num(s):return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]def str2int(s):return reduce(lambda x,y: x*10+y, map(char2num, s))

也就是说,假设Python没有提供int()函数,你完全可以自己写一个把字符串转化为整数的函数,而且只需要几行代码!

这就是函数的基本内容了!

参考

  • https://www.cnblogs.com/ghgyj/p/3997548.html

带你学python基础:函数是个function?相关推荐

  1. 带你学python基础:列表List

    在上一节中带你学python基础:变量和基本数据类型中,已经讲到了列表List如何创建和简单的使用,在这一节中,我们将更加细致入微的了解一下List更多的操作! 一.列表是什么? 列表是什么就是:一个 ...

  2. 带你学python基础:模块和包

    一.什么是模块 在我们平时的开发过程中,或多或少会用到 Python 的一些内置的功能,或者说,还会用到一些第三方的库,我们用到的这些 Python 的内置的功能,和一些第三方的库,就可以说是一些模块 ...

  3. 带你学python基础:字符串

    还记得学习 C 语言的时候吗,是不是每天都在控制台程序上玩耍,那时发现编程太没意思了,就只能玩这些东西吗? 后来,发现其实,外面的世界还是非常的广阔的,但是,今天,既然是 python 基础,所以我们 ...

  4. 带你学python基础:条件控制if与循环语句while、for 以及range函数

    一.什么是条件控制 条件控制用生活中的一个例子来说就是:当你去买车时,会有好多品牌,这个时候我们就需要做出选择,到底需要买哪个品牌的车,而在编程中,条件控制就是为了帮你做选择的. 用专业点的话来说,条 ...

  5. python跳出if条件_带你学python基础:条件控制if与循环语句while、for 以及range函数...

    一.什么是条件控制 条件控制用生活中的一个例子来说就是:当你去买车时,会有好多品牌,这个时候我们就需要做出选择,到底需要买哪个品牌的车,而在编程中,条件控制就是为了帮你做选择的. 用专业点的话来说,条 ...

  6. 带你学python基础:文件读写,俗称IO操作

    这一节讲个挺有意思的知识,至少在我以前刚刚接触编程的时候,对于文件操作还是觉得很有意思的事情,这也许是有一种操作文件的激情吧,希望看到这篇文章的读者也会有这样的激情,说明还是很有兴趣的,当然,就算没有 ...

  7. 带你学python基础:面向对象编程

    面向对象编程是个啥呢,其实,在传统的语言中,比如 C 语言,是不存在面向对象编程这个概念的,那时候的语言只有面向过程编程,也就是我们写代码从头写到底,最多也就是有函数.所以,这样的代码风格是比较难维护 ...

  8. 带你学python基础:元祖tuple和字典dictionary

    一.什么是元祖 如果你学过列表 List 的话,那么,你是否会觉得元祖和列表是不是特别的相似呢? 确实,是的.但是,他们之间也是有一些区别的. 而不同之处在于元祖的元素不能被修改,而列表的元素可以被修 ...

  9. 带你学python基础:变量和基本数据类型

    一.变量 1.1 什么是变量? 其实要理解变量是什么很简单,你只需要想象一下,我现在手里有好多的糖,但是放在手里一直抓着很累,所以,我需要有一个东西来装这些糖,所以,我们就拿了个袋子或者盒子来装这些糖 ...

最新文章

  1. NBT-新年4篇35分文章聚焦宏基因组研究
  2. 后台ajax调用中字符串到jquery中的json对象和数组对象转换问题
  3. 云栖社区 测试技术社区大群 正式成立!还在等什么,快来加入我们...
  4. 计算机组成原理与系统结构---内存编址方法
  5. 职高计算机教学案例 反思,关于职高数学优质课教学案例的研究与反思
  6. 如何将文件加添加成webapp
  7. 《ASP.NET Core 微服务实战》-- 读书笔记(第11章)
  8. 《大数据》2015年第3期“网络大数据专题”——网络大数据的文本内容分析
  9. 数据结构-王道-排序
  10. Excel中的图表制作(一) -各种商品销售量显示
  11. 考研总分多少能去辽师_考研英语作文平均分出炉,你拖后腿了吗?
  12. js字符串转日期类型
  13. fiddler手机抓包 443
  14. 计算机显示无法格式化,计算机格式化SD卡提示Windows无法完成格式化解决方法
  15. PyRadiomics工具包使用说明
  16. ios 通过代码调整焦距
  17. Android权限 - AppOps介绍
  18. C语言题目(数组)1
  19. 毕业设计 单片机指纹识别考勤系统 - 嵌入式 物联网
  20. DbGate:一款免费的智能数据库管理工具

热门文章

  1. 【备忘】visual studio调试状态下显示lua调用栈
  2. 关于用飞信框架运行net程序-用批处理运行
  3. XGBoost Plotting API以及GBDT组合特征实践
  4. Python 定时任务框架 APScheduler
  5. C++ Primer 5th笔记(chap 19 特殊工具与技术)类成员指针
  6. 数据结构--队列(链表实现)
  7. 全网最强Python版《超级玛丽》小游戏,我还是你的马里奥嘛?
  8. 【django】视图和URL
  9. TF-A代码阅读: 双系统切换时是如何保存寄存器的(cpu_context介绍)
  10. 专题目录20211013-ongoing