函数的返回值
- 返回值就是函数执行以后返回的结果
- 通过return来指定函数的返回值
- return后面可以接任意对象,甚至可以接一个函数
- 实例:
1 、 int --整数类型:
def fn(*args):
return 123
s = fn()
print(s)
打印输出结果:123
2 、str–字符串类型
def fn(*args):
return 'python'
s = fn()
print(s)
打印输出结果:python
3 、list–列表类型
def fn(*args):
return [1,2,3]
s = fn()
print(s)
打印输出结果:[1,2,3]
4 、tuple–元组类型
def fn(*args):
return (1,2,3,5,4)
s = fn()
print(s)
打印输出结果:(1,2,3,5,4)
5 、dict–字典类型
def fn(*args):
return {
'1': 1, '2' : 2}
s = fn()
print(s)
打印输出结果:{‘1’: 1, ‘2’: 2}
6 、函数对象
# 1
def fn():
def fn1():
print('我是fn1')
return fn1
s = fn()
print(s) # 返回值为函数对象--<function fn.<locals>.fn1 at 0x7f845fe045e0>
# 2
def fn():
def fn1():
print('我是fn1')
return {
'a': 123}
return fn1
s = fn()
print(s())
打印输出结果:
#1、
<function fn.<locals>.fn1 at 0x7fd8d1c045e0>
#2 、
我是fn1
{
'a': 123}
- 注:如果需要嵌套函数的返回值时,需要在最后打印返回值时添加括号来打印嵌套函数的返回值。
- 注:当代码中不写return语句或只写一个return的时候,返回值是None。
注:在函数中,return代表返回,return后面的代码不再执行
def fn():
for i in range(9):
print('abc')
return
print(123)
r = fn()
print(r)
打印输出结果:
abc
None
- 注:break与continue一定在循环内使用,只会对档次循环起作用。
def fn():
for i in range(9):
if i == 5:
# break
continue
print(i)
print('循环执行完毕')
# 在函数需要打印的时候,如果需要函数外打印,写不写return最后结果都是None.
r = fn()
print(r)
打印输出结果:
0
1
2
3
4
6
7
8
循环执行完毕
None
二、文档字符串
- help()函数是python中的内置函数,通过help()函数可以查询python中函数的用法。
- 在定义函数时,可以在函数内部编写文档字符串,文档字符串就是对函数的说明。
实例:
def fn(a, b, c):
"""
这是一个文档字符串的说明
通常我们用来对函数进行解释说明
:param a: 作用 类型 默认值
:param b: 作用 类型 默认值
:param c: 作用 类型 默认值
:return: 需要不需要
"""
return 123
help(fn)
打印输出结果:
Help on function fn in module __main__:
fn(a, b, c)
这是一个文档字符串的说明
通常我们用来对函数进行解释说明
:param a: 作用 类型 默认值
:param b: 作用 类型 默认值
:param c: 作用 类型 默认值
:return: 需要不需要
三、函数的作用域
- 函数的作用域:指的是变量生效的区域。
- 如果变量在函数内部,不能拿到函数外部使用
实例:
def fn():
a = 123
print('函数内部:a = ', a)
fn()
print('函数外部:a =', a)
打印输出结果:'函数外部:a = ', a—中的a未被定义,报错。
函数内部:a = 123
Traceback (most recent call last):
File "/Users/wangjiaxin/PycharmProjects/wangjiaxin/Python-Cheney老师基础讲解/第九讲/3--函数的作用域.py", line 11, in <module>
print('函数外部:a =', a)
NameError: name 'a' is not defined
-
函数的作用域分为两种:
- 全局作用域:
1 .在程序执行时创建,在程序执行结束时销毁
2 .所有函数以外的区域都是全局作用域
3 .在全局作用域中定义的变量,都是全局变量,全局变量可以在程序的任意位置进行访问 - 函数作用域:
1 .函数作用域在函数调用时创建,在函数调用结束时销毁
2 .函数每调用一次就会产生一个新的函数作用域
3 .在函数作用域中定义的变量,都是局部变量,它只能在函数内部进行访问
- 全局作用域:
-
如果想将局部变量转换成全局变量需要使用global来声明局部变量为全局变量。
实例:
b = 456
# a = [b]
def fn():
global a # 声明变量a时全局变量。
a = 123
print('函数内部:a = ', a)
print('函数内部:b = ', b)
fn()
print('函数外部:a =', a)
print('函数外部:b = ', b)
打印输出结果:
函数内部:a = 123
函数内部:b = 456
函数外部:a = 123
函数外部:b = 456
四、命名空间
- 命名空间实际上就是一个字典,是一个专门用来存储变量的字典。
- locals()函数用来获取当前作用域的命名空间。
- 在全局作用域当中调用locals()函数来获取全局命名空间。
- 在函数作用域当中调用locals()函数来获取函数命名空间。
- 返回值是一个字典。
locals()函数的使用很少。
演示实例1:
def fn():
a = 1
b = 2
c = 3
d = 4
scope = locals()
scope['e'] = 5
print('e')
print(scope)
fn()
打印输出结果:
e
{
'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
分析:对变量scope使用locals()函数返回的值是一个字典。
演示实例2:
def fn():
a = 1
b = 2
c = 3
d = 4
scope = globals()
scope['e'] = 5
print(e)
print(scope)
fn()
打印输出结果:
5
{
'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7fc917e54400>, '__spec__': None, '__annotations__': {
}, '__builtins__': <module 'builtins' (built-in)>, '__file__': '/Users/wangjiaxin/PycharmProjects/wangjiaxin/Python-Cheney老师基础讲解/第九讲/4--命名空间.py', '__cached__': None, 'fn': <function fn at 0x7fc9194045e0>, 'e': 5}
分析:声明scope为全局变量。
五、递归函数
- 递归是解决问题的一种方式,它的整体思想,是将一个大问题分解为一个个的小问题,直到问题无法分解时,再去解决问题。
- 递归函数的两个基本条件:
- 1 .基线条件:问题可以被分解为最小问题,当满足基线条件时,递归就不执行了。
- 2 .递归条件: 可以讲问题继续分解的条件。
演示实例:
求10的阶乘(10!)
# 普通方法:
n = 10
for i in range(1,10):
n *= i
print(n)
# 函数法:
def fn(n):
for i in range(1,n):
n *= i
return n
r = fn(10)
print(r)
打印输出结果:3628800、3628800
由上述实例分析:递归函数就是自己调用自己。
递归函数演示实例
# 递归函数法:
def fn(n): # 定义的fn()函数就是要计算n的阶乘
# 基线条件
if n == 1:
return 1
# 递归条件
return n * fn(n-1)
r = fn(10) # r = 10* fn(9) # r = 10 * 9 * fn(8)
print(r)
打印输出结果:3628800
分析:
1.首先确定基线条件
2.再确定递归条件,由return返还函数计算公式来分解计算问题。
六、递归函数联系
练习一:
定义一个函数,为任意数字作任意的幂运算。
def fn1(n,m): # fn1() 是做n ** m次幂的运算
if m == 1:
return n
return n * fn1(n , m - 1)
r = fn1(10,8)
print(r)
打印输出结果:100000000
练习二:
定义一个函数,用来检查任意的一个字符串是不是一个回文字符串,如果是返回Ture,如果不是返回false。
def fn2(str1):# fn2()判断字符串是不是回文字符串
if len(str1) < 2:
return True
elif str1[0] != str1[-1]: # !=为不等于号
return False
return fn2(str1[1:-1])
s = fn2('abcdefghgfedcba')
print(s)
打印输出结果:True
七、 课后作业
作业一:
'''
用函数实现一个判断用户输入的年份是否是闰年的程序
1.能被400整除的年份
2.能被4整除,但是不能被100整除的年份
以上2种方法满足一种即为闰年
'''
# 闰年的基本概念:所输入年份除4和400二者无余数则为闰年。
# 1.定义一个函数:
def fn(year):
print('请输入年份:{}'.format(year))
while True:
year = int(input('请输入公立年份:'))
# 使用if判断取余:
# 如果输入的年份years可以被400整除取余为0:
if year % 400 == 0:
print('您输入的年份{}是闰年!'.format(year))
# 如果输入的年份years可以被4整除取余为0和不能被100整除取余不为0:
elif year % 4 == 0 and year % 100 != 0:
print('您输入的年份{}是闰年!'.format(year))
else:
print('您输入的年份{}不是闰年!'.format(year))
fn(year)
打印输出结果:
请输入公立年份:2008
您输入的年份2008是闰年!
请输入公立年份:2009
您输入的年份2009不是闰年!
请输入公立年份:1
您输入的年份1不是闰年!
请输入公立年份:4
您输入的年份4是闰年!
请输入公立年份:8
您输入的年份8是闰年!
请输入公立年份:12
您输入的年份12是闰年!
- 分析:
本题的题意会让你第一时间联想带input()函数与整除算法。但是细致分析过分,用来判断的三个条件不满足整除算法,需要使用除法取余,来完成该题的三个条件。
为了使整个函数可以多次输入,则使用while Ture:循环,内部使用if判断语句来鉴别这三个条件,从而得到想要的结果。
作业二:
'''
2. 猴子吃桃问题(递归):
猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个。第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩的一半零一个。到第10天早上想再吃时,见只剩下一个桃子了,求第一天共摘了多少桃子?
'''
# 方法一:
peach = 1
for day in range(1,10):
peach = (peach + 1) * 2
print(peach)
# 方法二:
def fn(day):
# 当天数等于10时,返还为1
if day == 10:
return 1
# 调用返还每天猴子吃桃的数量
return (fn(day+1)+1)*2
r = fn(1)
# r = 1+4+10+。。。
print(r)
打印输出结果:
1534
1534
分析:
根据题意,就可以计算出该题的基本运算公式:(p+1)*2或p/2-1。
猴子第一天摘的桃子为偶数才能符合题意。
通过递归函数,递归函数本身,返回天数与桃子的关系运算,从而得出猴子摘桃子的数量。
注:其实这道通不需要算,你想想啊,猴子第一天吃了700多的桃子早就撑死了,还吃什么吃,第十天桃子都烂了。还哪里有桃子了!