函数概述
在python中,使用def关键字声明一个函数。Def行的最后必须加冒号。函数的实现需要缩进。格式:
def 函数名(形参):
函数的实现
然后,通过如下方法调用函数
函数名(实参)
比如:无参数的函数
# 声明一个无参数的函数
defsayHello():
print('helloworld')
# 调用无参数的函数
sayHello()
PS. 函数的类型是function
print(type(sayHello)) # <class 'function'>
有参数的函数
# 声明一个带一个参数的函数
defprintValue(value):
print('参数为', value)
# 调用带一个参数的函数
printValue(9527)
# 声明一个带两个参数的函数
defprintSum(a, b):
print('和为', (a + b))
# 调用带两个参数的函数
printSum(3,8)
函数的参数可以指定默认值。如果调用函数的时候,没有传递该参数,则使用默认值
# 指定默认值的函数
defprintSum1(a = 3, b = 5):
print('和为', (a + b))
printSum1(2,8) # 10 给a和b都传递参数
printSum1(2) # 7 只给a传递参数2 b使用默认值5作为参数
printSum1() # 8 a和b都使用默认值作为参数
printSum1(b = 2) # 5 只给b传递参数2 a使用默认值3作为参数
print(a = 2, b = 7) # 在传递参数的时候指定参数名
print(b = 2, a = 7) # 在传递参数的时候指定参数名的时候 可以颠倒参数的顺序
函数可以通过return关键字返回值。如果不写return,就认为返回None
# 没有返回值的函数
defsum1(a, b):
sum = a + b
# 没有返回值
# return None
result = sum1(3,8)
print(result) # None
print(type(result)) # <class 'NoneType'>
# 有一个返回值的函数
defsum2(a, b):
sum = a + b
# 有一个返回值
return sum
result = sum2(3,8)
print(result) # 11
# python特有
# 有两个返回值的函数
# 实际上返回的是一个元组
defsum3(a, b):
sum1 = a + b
sum2 = a * b
return sum1, sum2
result1, result2 = sum3(3, 8)
print(result1, result2) # 11 12
result = sum3(3, 8)
print(result) # (11, 24)
print(type(result)) # <class 'tuple'>
思考:
defaddOne(a):
a = a + 1
value1 = 5
addOne(value1)
print(value1) # 5
输出结果是5而不是6,为什么?
可变参数*args和**kwargs
其中args是元组;kwargs是字典
思考:写一个函数sum()要求:
sum(1,2)=3
sum(1,2,3)=6
sum(1,2,3,4)=10
………………
sum(1,2,3,4,……,100)=5050
def sum(*args):
# args是可变参数 类型为元组
#print(args)
result = 0
for i in args:
result += i
return result
print(sum(1) == 1) # True
print(sum(1,2) == 3) # True
print(sum(1,2,3) == 6) # True
print(sum(1,2,3,4) == 10) # True
print(sum(1,2,3,4,5) == 15) # True
参考下面的例子
def fun(value1, value2, value3 = 0, *args, **kwargs):
print('value1 = ', value1, 'value2 = ', value2, 'value3 = ', value3, 'args = ', args, 'kwargs = ', kwargs)
fun(1,2) # value1 = 1 value2 = 2 value3 = 0 args = () kwargs = {}
fun(1,2,3) # value1 = 1 value2 = 2 value3 = 3 args = () kwargs = {}
fun(1,2,3,4) # value1 = 1 value2 = 2 value3 = 3 args = (4,) kwargs = {}
fun(value1=4,value2=5,value3=6) # value1 = 4 value2 = 5 value3 = 6 args = () kwargs = {}
fun(value1=4,value2=5,value3=6,value4=7) # value1 = 4 value2 = 5 value3 = 6 args = () kwargs = {'value4': 7}
fun(1,2,'hello','world') # value1 = 1 value2 = 2 value3 = hello args = ('world',) kwargs = {}
fun(1,2,3,'hello','world') # value1 = 1 value2 = 2 value3 = 3 args = ('hello', 'world') kwargs = {}
fun(1,2,3,'zhangsan',23,178.3) # value1 = 1 value2 = 2 value3 = 3 args = ('zhangsan', 23, 178.3) kwargs = {}
fun(1,2,3,name='zhangsan',age=23,height=178.3) # value1 = 1 value2 = 2 value3 = 3 args = () kwargs = {'name': 'zhangsan', 'age': 23, 'height': 178.3}
global和nonlocal
思考如下问题:
a = 10
def fun():
value = a + 1
print('a = %d, value = %d' % (a, value))
fun() # a = 10, value = 11
此时是正常输出的
但如果改成
a = 10
deffun():
a = a + 1
value = a + 1
print('a = %d, value = %d' % (a, value))
fun()
程序就会报错,原因是:
-
左边的a是fun函数栈上的变量
-
右边的a根据就近原则 如果函数栈上有变量则先访问函数栈上的
-
此时会报referenced before assignment的错误(先访问再赋值)
-
修改方法:在a=a+1前,强制声明a变量是全局变量
a = 10
def fun():
global a # 强制声明a为全局变量
a = a + 1
value = a + 1
print('a = %d, value = %d' % (a, value))
fun()
如果一个变量是非全局的,非局部的。通常是指在嵌套作用域的外层,此时需要使用nonlocal来声明。
def outer():
num = 10 # 这个变量在外部函数的里面 在内部函数的外面
def inner():
nonlocal num
num = num + 1
inner()
print(num)
递归
递归就是函数调用自己本身。特别容易出现死循环,而且会出现内存崩溃。
递归一般需要做两件事:
-
1 找出口
-
2 找进入下一层的方式
比如:通过递归函数求阶乘
-
5! = 1*2*3*4*5
-
fac(n)=n*fac(n-1)
# 递归函数求阶乘
def fac(n):
# 1 找出口
if n == 1 or n == 0:
return 1
# 2 找进入下一层的方式
return n * fac(n-1)
print(fac(3))
print(fac(10))
匿名函数:lambda表达式
Lambda指的是λ
慎用
如果一个函数代码量较少(一行起,两行止),可以考虑使用lambda表达式。
# 普通函数
# 普通函数
def add(x,y):
return x + y
result = add(3,5)
print(result)
# 匿名函数
add = lambda x,y: x + y
result = add(4,7)
print(result)
Lambda表达式也可以设置默认值。
# 给参数设置默认值
add = lambda x = 2,y = 5: x + y
print(add(4,7)) # 11
print(add(4)) # 9
print(add()) # 7
print(add(y = 9)) # 11
练习
猜数。自己先想一个1~100之间的数,写一个程序去猜这个数。
电脑输出:请先想好一个1\~100之间的数,按回车继续
(假设用户想的是78)
电脑猜50,用户反馈:小了
电脑猜75,用户反馈:小了
电脑猜87,用户反馈:大了
……………………
电脑猜78,用户反馈,中了
程序结束
本章项目源码
URL:https://gitee.com/yuanbaonet/master_python/tree/baoai_python_v7/
对应版本:baoai_python_v7
对应文件:sample/python/p7.py