Python基础语法——函数
1.函数介绍
- 函数时Python语言程序的基本单位,Python语言程序的功能就是靠每一个函数实现的,由于函数可以重复使用,因此函数能够提高应用的模块性和代码的重复利用率,在Python中除了内置函数外,还可以自定义函数。
- 函数是指一组语句的集合,通过一个名字(函数名)封装起来,要想执行这个函数,只需要调用这个函数名即可。
- 如果在开发程序时,需要某块代码多次,但是为了提高编写的效率以及代码的重用,所以把具有独立功能的代码块组织为一个小模块,这就是函数
- 函数可重复调用,是的代码更简洁,易读。
- 函数是组织好的,可重复使用的用来实现单一或相关功能的代码段。
- 通过将一组语句封装成函数成为一个代码块,更有利于调试和后期的修改。
2.函数的定义、调用
(1)函数定义
- 根据实际工作的需求,用户可以自己创建函数,即用户自定义函数。
- Python函数定义方法是使用def关键字,语法格式如下:
def 函数名称(参数1,参数2,参数3........)
“文件字符串”
函数体
- “文件字符“”串是可以省略的,用来作买书此函数的字符串,文件字符串存在的话必须是函数的第一个语句
- return[表达式]结束函数,选择性的返回一个值给调用方,不带表达式的return相当于返回None
- 定义一个函数,主要是指定函数里包含的参数和代码块
(2)函数调用
- 定义了函数之后,就相当于有了一个具有某些功能的代码,想要让这些代码能够执行,需要调用它调用函数很简单的,通过 数名() 即可完成调用
- 或者把这个函数赋值给一个变量,然后打印这个变量
(3)调用内置函数
Python内置的函数及其用法。为了方便记忆,已经有很多开发者将这些内置函数进行了如下分类:
数学运算(7个)
类型转换(24个)
序列操作(8个)
对象操作(7个)
反射操作(8个)
变量操作(2个)
交互操作(2个)
文件操作(1个)
编译执行(4个)
装饰器(3个)
详情见原文链接:https://blog.csdn.net/alice_tl/java/article/details/80867196
3.函数的参数
- Python的参数传递都是使用传址调用的方式,所谓传址调用,就是将该参数的内存地址传过去,若参数在函数内被更改,则会影响到原有参数,参数的数据类型可以是模,类,示例,或者其他的函数,不必在参数内设置参数的类型。
- 调用函数时可以使用参数的参数类型包括必须参数,关键字参数,默认参数,可变参数和组合参数。
(1)必须参数
必须以正确的顺序传入参数,调用时参数的数量必须和声明时的一样,设置参数时必须按照他们的位置排列顺序
(2)关键参数
用户调用的时候可以直接设置参数的名称及其默认值,此时设置参数是可以不按照定义函数时的参数顺序。
(3)默认参数(缺省参数)
调用函数时如果没有传入参数,则会使用默认参数;若调用时传入参数,优先使用调用时设置的参数
(4)不定长参数
- 有时可能需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数,声明时不会命名。
基本语法如下:
- *args:表示所有不定量未命名(非键值对)的参数(不定量指预先不知道函数使用者或传递多少个参数给这个函数,并一元 组形 式保存起来)
- *keyargs:表示将不定产度的键值对作为参数传递给一个函数,可以在函数里处理带名字(字典形式)的参数
- 加了星号(*)的变量args会存放所有未命名的变量参数,args为元组;而加**的变量kwargs会存放命名参数,即形如 key=value的参数, kwargs为字典。
(5)引用传参
- 可变类型与不可变类型的变量分别作为函数参数时,会有什么不同吗?
- Python有没有类似C语言中的指针传参呢?
- Python中函数参数是引用传递(注意不是值传递)。对于不可变类型,因变量不能修改,所以运算不会影响到变量自身;而对于可变类型来说,函数体中的运算有可能会更改传入的参数变量。
注意:a=a+a与a+=1不一样
a=a+a:把原来的拿过来,生成新的即地址会改变相当于重新定义了一个变量,与运算之前的那个a不是同一个a
a+=a:在原来的基础上直接改,不改变运算前a的地址。
eg1:a=a+a
eg:a+=a
4.函数返回值
(1)返回值”介绍
现实生活中的场景:
我给儿子10块钱,让他给我买包烟。这个例子中,10块钱是我给儿子的,就相当于调用函数时传递到参数,让儿子买烟这个事情最终的目标是,让他把烟给你带回来然后给你对么,,,此时烟就是返回值
开发中的场景:
定义了一个函数,完成了获取室内温度,想一想是不是应该把这个结果给调用者,只有调用者拥有了这个返回值,才能够根据当前的温度做适当的调整
综上所述:
- 所谓“返回值”,就是程序中函数完成一件事情后,最后给调用者的结果
(2)有返回值的函数
想要在函数中把结果返回给调用者,需要在函数中使用return
如下示例:
def add2num(a, b):
c = a+b
return c
或者:
def add2num(a, b):
return a+b
(3)保存函数的返回值
在本小节刚开始的时候,说过的“买烟”的例子中,最后儿子给你烟时,你一定是从儿子手中接过来 对么,程序也是如此,如果一个函数返回了一个数据,那么想要用这个数据,那么就需要保存
保存函数的返回值示例如下:
#定义函数
def add2num(a, b):
return a+b
#调用函数,顺便保存函数的返回值
result = add2num(100,98)
#因为result已经保存了add2num的返回值,所以接下来就可以使用了
print result
结果:
198
(4)return语句返回数值的方法
- 返回以赋值的变量名 a=x+y return a
- 返回表达式:return x+y
- 返回值可以是多个,此时返回值以元组对象返回
- 没有返回值,则返回None
5.4种函数类型
函数根据有没有参数,有没有返回值,可以相互组合,一共有4种
- 无参数,无返回值
- 无参数,又反悔
- 有参数,无返回值
- 有参数,有返回值
(1)无参数,无返回值的函数
此类函数,不能接收参数,也没有返回值,一般情况下,打印提示灯类似的功能,使用这类的函数
def printMenu():
print('--------------------------')
print(' xx涮涮锅 点菜系统')
print('')
print(' 1. 羊肉涮涮锅')
print(' 2. 牛肉涮涮锅')
print(' 3. 猪肉涮涮锅')
print('--------------------------')
结果:
(2)无参数,有返回值的函数
此类函数,不能接收参数,但是可以返回某个数据,一般情况下,像采集数据,用此类函数
# 获取温度
def getTemperature():
#这里是获取温度的一些处理过程
#为了简单起见,先模拟返回一个数据
return 24
temperature = getTemperature()
print('当前的温度为:%d'%temperature)
结果:
当前的温度为: 24
(3)有参数,无返回值的函数
此类函数,能接收参数,但不可以返回数据,一般情况下,对某些变量设置数据而不需结果时,用此类函数
(4)有参数,有返回值的函数
此类函数,不仅能接收参数,还可以返回某个数据,一般情况下,像数据处理并需要结果的应用,用此类函数
# 计算1~num的累积和
def calculateNum(num):
result = 0
i = 1
while i<=num:
result = result + i
i+=1
return result
result = calculateNum(100)
print('1~100的累积和为:%d'%result)
结果:
1~100的累积和为: 5050
(5)小总结
- 函数根据有没有参数,有没有返回值可以相互组合
- 定义函数时,是根据实际的功能需求来设计的,所以不同开发人员编写的函数类型各不相同
6.形参和实参
函数的参数分为实参和形参两种,形参出现在函数定义中,在整个函数体内都可以使用,离开该函数则不能使用。实参在调用函数时传入。
(1)实参与形参的概念
- 形式参数:在函数定义中出现的参数,可以看做是一个占位符,它没有数据,只有等到函数被调用时接受传递进来的数据。
- 实际参数:函数被调用时给出的参数,包含实实在在的数据,会被函数内部的代码使用。
(2)参数的功能:实参和形参的功能都是数据传送,发生函数调用时,实参的值会传给形参。
(3)实参和形参的特点
- 形参变量只有在函数调用时才会被分配内存,调用结束后立刻释放内存,所以形参变量只有在函数内部才有效,不能在函数外部使用
- 实参可以是常量,变量,表达式,函数等,无论实参是何种类型的数据,在进行函数调用时,都必须有确定的值,以便八这些值传递给形参,所以应该提前用赋值,输入等办法使实参获得确定值。
- 实参在数量上、类型上、顺序上必须严格一致,否则会发生“类型不匹配”的错误
- 函数调用中发生的数据传送是单向的,即只能把实参的值传递给形参,而不能把形参的值反向地传给实参,因此在函数的调用过程中,形参值发生改变时,实参的值不会因形参的改变而改变。
- 在定义函数时,函数的参数就是形参,形参即形式上的参数,它代表参数,但不知到具体代表什么参数,实参就是调用函数是的参数,即具体的已经知道的参数。
7.函数的嵌套调用
def testB():
print('---- testB start----')
print('这里是testB函数执行的代码...(省略)...')
print('---- testB end----')
def testA():
print('---- testA start----')
testB()
print('---- testA end----')
testA()
结果:
---- testA start----
---- testB start----
这里是testB函数执行的代码...(省略)...
---- testB end----
---- testA end----
小总结:
- 一个函数里面又调用了另外一个函数,这就是所谓的函数嵌套调用
- 如果函数A中,调用了另外一个函数B,那么先把函数B中的任务都执行完毕之后才会回到上次 函数A执行的位置
8.返回函数
在Python中,函数不仅可以作为其他函数的参数,还可以作为其他函数的返回结果。
9.递归函数
递归函数
(1)什么是递归函数
通过前面的学习知道一个函数可以调用其他函数。
如果一个函数在内部不调用其它的函数,而是自己本身的话,这个函数就是递归函数。
(2)递归函数的作用
举个例子,我们来计算阶乘 n! = 1 * 2 * 3 * ... * n
解决办法1:
看阶乘的规律
1! = 1
2! = 2 × 1 = 2 × 1!
3! = 3 × 2 × 1 = 3 × 2!
4! = 4 × 3 × 2 × 1 = 4 × 3!
...
n! = n × (n-1)!
解决办法2:
原理
10.匿名函数
(1)用lambda关键词能创建小型匿名函数。这种函数得名于省略了用def声明函数的标准步骤。若用户的函数只有一个表达式,可以用lambda运算符来定义这个函数。
lambda函数的语法只包含一个语句,如下:
lambda [arg1 [,arg2,.....argn]]:expression
如下实例:
sum = lambda arg1, arg2: arg1 + arg2
#调用sum函数
print "Value of total : ", sum( 10, 20 )
print "Value of total : ", sum( 20, 20 )
以上实例输出结果:
Value of total : 30
Value of total : 40
(2)lambda创建函数的优点
- 使用lambda可以省去定义函数的过程,让代码更加精简
- 对于一些抽象的,不会用在其他地方再重复使用的函数,取名字也是一个难题,使用lambda则不需要考虑命名的问题
(3)lambda 创建函数的规则
- 可以有一个参数,也可以没有参数
- 不能有return
- Lambda函数能接收任何数量的参数但只能返回一个表达式的值
- 匿名函数不能直接调用print,因为lambda需要一个表达式
- 若只有一个表达式,则必细有返回值
- lambda匿名函数的格式:冒号前是参数,可以有多个,用逗号隔开,冒号右边的为表达式。其实lambda返回值是一个函数的地址,也就是函数对象。如需要一个变量接收它即,一个个对象。
(4)应用场合
- 函数作为参数传递
自己定义函数
>>> def fun(a, b, opt):
... print "a =", a
... print "b =", b
... print "result =", opt(a, b)
...
>>> fun(1, 2, lambda x,y:x+y)
a = 1
b = 2
result = 3
- 作为内置函数的参数
想一想,下面的数据如何指定按age或name排序?
stus = [
{"name":"zhangsan", "age":18},
{"name":"lisi", "age":19},
{"name":"wangwu", "age":17}
]
按name排序:
>>> stus.sort(key = lambda x:x['name'])
>>> stus
[{'age': 19, 'name': 'lisi'}, {'age': 17, 'name': 'wangwu'}, {'age': 18, 'name': 'zhangsan'}]
按age排序:
>>> stus.sort(key = lambda x:x['age'])
>>> stus
[{'age': 17, 'name': 'wangwu'}, {'age': 18, 'name': 'zhangsan'}, {'age': 19, 'name': 'lisi'}]
11.函数的内置属性和命名空间
(1)显示内置属性 dir((函数名)
(2)常见属性:
- __dict__:该属性包含函数的命名空间
- __doc__:该属性显示函数的文件字符串
- __name__:该属性显示函数名
(3)命名空间:
- 内置命名空间:int,string,def,print 等,记录Python自身提供的函数,模块等被命名的对象,通过模块名.变量名来访问模块中的对象
- 全局命名空间:位于模块的最上层。记录模块的变量、函数、类自己其导入的模块等被命名的对象。
- 局部命名空间:位于函数内
12.全局变量
(1)什么是全局变量
如果一个变量,既能在一个函数中使用,也能在其他的函数中使用,这样的变量就是全局变量
demo如下:
# 定义全局变量
a = 100
def test1():
print(a)
def test2():
print(a)
# 调用函数
test1()
test2()
运行结果:
(2)全局变量和局部变量名字相同问题
如果全局变量的名字和局部变量的名字相同,那么使用的是局部变量的
:
(3)修改全局变量
既然全局变量,就是能够在所以的函数中进行使用,那么可否进行修改呢?
代码如下:
(4)总结:
- 在函数外边定义的变量叫做
全局变量
- 全局变量能够在所有的函数中进行访问
- 如果在函数中修改全局变量,那么就需要使用
global
进行声明,否则出错 - 如果全局变量的名字和局部变量的名字相同,那么使用的是局部变量的,小技巧
强龙不压地头蛇
(5)可变类型的全局变量
>>> a = 1
>>> def f():
... a += 1
... print a
...
>>> f()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in f
UnboundLocalError: local variable 'a' referenced before assignment
>>>
>>>
>>> li = [1,]
>>> def f2():
... li.append(1)
... print li
...
>>> f2()
[1, 1]
>>> li
[1, 1]
(5)总结2:
- 在函数中不使用global声明全局变量时不能修改全局变量的本质是不能修改全局变量的指向,即不能将全局变量指向新的数据。
- 对于不可变类型的全局变量来说,因其指向的数据不能修改,所以不使用global时无法修改全局变量。
- 对于可变类型的全局变量来说,因其指向的数据可以修改,所以不使用global时也可修改全局变量。
13.局部变量
(1)什么是局部变量
如下图所示:
(2)小总结
- 局部变量,就是在函数内部定义的变量
- 不同的函数,可以定义相同的名字的局部变量,但是各用个的不会产生影响
- 局部变量的作用,为了临时保存数据需要在函数中定义变量来进行存储,这就是它的作用
14.函数使用注意事项
(1) 自定义函数
A.无参数、无返回值
def 函数名():
语句
B.无参数、有返回值
def 函数名():
语句
return 需要返回的数值
注意:
- 一个函数到底有没有返回值,就看有没有return,因为只有return才可以返回数据
- 在开发中往往根据需求来设计函数需不需要返回值
- 函数中,可以有多个return语句,但是只要执行到一个return语句,那么就意味着这个函数的调用完成
C.有参数、无返回值
def 函数名(形参列表):
语句
注意:
- 在调用函数时,如果需要把一些数据一起传递过去,被调用函数就需要用参数来接收
- 参数列表中变量的个数根据实际传递的数据的多少来确定
D.有参数、有返回值
def 函数名(形参列表):
语句
return 需要返回的数值
E.函数名不能重复
(2)调用函数
A.调用的方式为:
函数名([实参列表])
B.调用时,到底写不写 实参
- 如果调用的函数 在定义时有形参,那么在调用的时候就应该传递参数
C.调用时,实参的个数和先后顺序应该和定义函数中要求的一致
D.如果调用的函数有返回值,那么就可以用一个变量来进行保存这个值
(3)作用域
A.在一个函数中定义的变量,只能在本函数中用(局部变量)
B.在函数外定义的变量,可以在所有的函数中使用(全局变量)
本文地址:https://blog.csdn.net/weixin_48052275/article/details/107603347