函数-过程-行为-动作:实现了某一功能或某些功能指令的集合。
(1).如何定义函数
格式:
def 函数名([参数列表]):
"""
文档注释
"""
函数体
[return 返回值] --返回值可以是多个
(2).如何调用函数(函数定义完成后,并不会自己调用,等待调用者调用)
格式:
函数名([实参列表])
注:
可以通过 函数名.__doc__ 属性来查看该函数的文档注释,能够了解此函数到底是用来做什么的
print(函数名.__doc__)
函数的调用过程:函数调用本质就是压栈,调用完成后会进行弹栈
(3).函数的分类
1.以函数是否存在参数:有参数、无参数
2.以是否存在返回值:有返回值、无返回值
3.定义者来分类:系统:python官方定义好的,内置daocpython解释器内部的、第三方:公司 组织 个人 、自定义
(4).变量分类
1.全局(本地local)变量:在Python中,定义在py文件的变量
特点:在代码运行时,变量始终有效(不是手动回收)
2.局部变量:定义在函数中的变量,当函数被垃圾机制回收时,该变量也会被回收掉。
注1:在函数外面不能访问函数内部定义变量(局部变量),反过来说,在函数内部可以访问本地变量(全局变量)。
注2:若在函数中要修改全局变量,就要使用关键字global申明(不建议修改全局变量的值).
age=17
def show_info():
global age
age=18
return age
print(show_info())
结果:18
注3:函数弹栈,全局变量不弹栈(全局变量常驻内存)
(5).值传递,引用传递(传递对象)
1.值传递:
import math
def getcircle_girth(r):
""" 计算圆的周长:"""
if r<=0:
print("输入的半径非法")
return None
else:
return 2*math.pi*r
r=float(input("请输入圆的半径:"))
print(getcircle_girth.__doc__)
print(getcircle_girth(r))
2.引用传递:强数据类型语言中,函数不允许嵌套、包含函数,弱类型
语言可以让函数的内存地址成为实参,传递到另一个函数的形参中,进
行引用传递。
def info(fn,msg):
fn()
print(msg)
def print_msg():
print("我自己定义的函数")
info(print_msg,"haha")
#将print_msg函数的内存地址作为实参,传递到info函数的形参fn中,
然后通过fn()去调用print_msg函数
结果如下:
我自己定义的函数
haha
注1:在弱数据类型语言中,万物皆对象,函数也是对象,所以函数就
可以进行引用传递
注2:函数名称就是指函数本身的内存地址,列表名就是指列表本身的
内存地址,即对象名就是对象本身的内存地址
(6).python中的main函数:写在main函数中的代码并不会导入到其他模块中
print("aaaa")
def show():
print("bbbb")
if __name__=="__main__":
show()
结果如下:
aaaa
bbbb
注:python代码并不是从main函数入口的!!!python代码是脚本,
是从上而下运行的
(7).函数参数
1.默认值参数:在调用的时候,如果给这个参数赋值了,则按照赋值
的情况算;如果没有赋值,也不报错,按照默认值算。
def get_cicle_cal(r,PI=3.14):#默认值参数
return 2*PI*r
r=float(input("请输入圆的半径:"))
cal=get_circle_cal(r,3.1415926)
print(cal)
2.可变参数:可以传递多个实际参数,可以传值,也可以不传值
def show(a,b,*args):
print(a+b)
# args以元组的方式将剩余参数封装起来
print(args)
print(args[0])
show(2,3,4,5,6)
结果如下:
5
(4, 5, 6)
4
3.关键字参数(命名参数):可以传值(键值对),也可以不传值
def show_info(x,**kwargs):
print(x)
# kwargs以字典的方式将剩余参数封装起来
print(kwarges)
print(kwargs["name"])
print(kwargs.get("age"))
show_info(1024,name="python",age=17)
结果如下:
1024
{'name': 'python', 'age': 17}
python
17
4.万能参数:
def test(a,b,*args,**kwargs):
print(a+b)
print(args)
print(kwargs)
test(2,3,4,5,name="python",age=17)
结果如下:
5
(4,5)
{'name':'python','age':17}
注:参数顺序:普通参数,默认值参数,可变参数,关键字参数
(8).函数递归:函数自身调用自身。
前提条件:1.自身调用自身
2.必须要有终止条件
注:如果递归中没有结束条件,会形成死循环(python规定最大递归
1000层,因为递归太多,会导致栈内存满,电脑死机)
例题:求和0到100
方法一:
def get_sum(n,m):
sum=0
if n>m:
n,m=m,n
for i in range(n,m+1):
sum+=i
return sum
if __name__=="__main__":
s=get_sum(100,0)
print(s)
结果:
5050
方法二:
def get_sum2(n):
if n==0:
return 0
else:
return n+get_sum2(n-1)
print(get_sum2(100))
结果:
5050
(9).匿名函数:(没有名称的函数)–lambda表达式
格式:
lambda[参数列表]:代码 #返回值不需要写return
特点:创建的时候就用,当一个函数要使用且使用一次,就可以使用匿名函数,可以优化代码,但也有缺点,降低了可读性,增加了维护性
注:一般lambda,也就是匿名函数,一般表示的是简单的函数(一行或者两行)
def show(fn):
res=fn(10,20)
print(res)
show(lambda a,b:a*b)
结果:
200
(10).偏函数:在python中,我们有时候需要调用某个函数,如果想将该函数中的某个参数设置一个固定值,那么就可以使用偏函数,使用functools模块里的partial()去重构一个函数
格式:
partial(函数名,参数=固定值)
例题:
#这里我们跟导模块的两种方法结合起来:
方法一:
import functools #导入的是functools模块的全部属性和方法
new_int=functools.partial(int,base=8) #用partial方法时,要用functools模块调用
print(new_int('23154'))
结果:
9836
方法二:
from functools import partial #导入的是functools模块的partial这一个方法
new_int=partial(int,base=8) #用partial方法时就不用模块调用了
print(new_int('23154'))
结果:
9836
注:int()全局函数里的base参数的默认值是10,如果在某些地方需要
将该参数的默认值修改,就可用到偏函数