Python学习第九课-函数二
一、函数的返回值
- 函数的调用可以是一个函数运行起来
- 函数的调用可以传递实参
- 函数的调用可以接受函数的返回值
def fun(*args):
r = 0
for i in args:
r+=i
print(r) #这个结果只是让我们能够观测到,就像镜中花,水中月,不能实际调用
fun(1,2,3,4,5)#不调用这个函数的话,函数fun()不回执行
'''
15
'''
比如
def fun(*args):
r = 0
for i in args:
r+=i
print(r)#r的值 会报错 未定义
#return r
fun(1,2,3,4,5)
r = r+1
'''
NameError: name 'r' is not defined
'''
def fun(*args):
global r # 需要使用 global 关键字声明
r = 0
for i in args:
r+=i
return r
return 'abc'
#return后面跟随的返回值会返回出去,
#return后面的代码不再执行
print(fun(1,2,3,4,5))
r = r+1
print(r)
'''
15
16
'''
def fun2():
for i in range(5):
if i==3:
break
print(i)
print('循环执行完成')
print(fun2())
'''
0
1
2
循环执行完成
None
'''
def fun2():
for i in range(5):
if i==3:
continue
print(i)
print('循环执行完成')
print(fun2())
'''
0
1
2
4
循环执行完成
None
'''
def fun2():
for i in range(5):
if i==3:
return #当存在return的时候,return后面不跟任何内容 返回None
print(i)
print('循环执行完成')
print(fun2())
'''
0
1
2
None
'''
def fun2():
for i in range(5):
if i==3:
#当没有return的时候,也没有返回值
pass
print(i)
print('循环执行完成')
print(fun2())
'''
0
1
2
3
4
循环执行完成
None
'''
def fun2():
for i in range(5):
if i==3:
return i
print('循环执行完成')
print(fun2())
'''
3
'''
``
```python
def fun2():
for i in range(5):
if i==3:
return i
print('循环执行完成')
print(fun2)
print(fun2())
'''
<function fun2 at 0x7fb0e72a2700>
3
## 总结:fun是函数对象,打印fun打印出来的结果是id地址
## fun()函数的调用 ,打印fun(),打印出的结果是函数的返回值`
'''
二、文档字符串
- 在定义函数时,可以在函数内部编写⽂档字符串,⽂档字符串就是对函数的说明
def fun(a,b):
'''
:param a:
:param b:
:return:
'''
pass
- help()是Python中内置函数,通过help()函数可以查询Python中函数的⽤法
help(print)
'''
Help on built-in function print in module builtins:
print(...)
print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
Prints the values to a stream, or to sys.stdout by default.
Optional keyword arguments:
file: a file-like object (stream); defaults to the current sys.stdout.
sep: string inserted between values, default a space.
end: string appended after the last value, default a newline.
flush: whether to forcibly flush the stream.
'''
三、函数的作用域
- 作⽤域(scope)
- 作⽤域指的是变量⽣效的区域
- 在Python中⼀共有两种作⽤域
3.1 全局作⽤域
- 全局作⽤域在程序执⾏时创建,在程序执⾏结束时销毁
- 所有函数以外的区域都是全局作⽤域
- 在全局作⽤域中定义的变量,都是全局变量,全局变量可以在程序的任意位置进⾏访问
3.2 函数作⽤域
- 函数作⽤域在函数调⽤时创建,在调⽤结束时销毁
- 函数每调⽤⼀次就会产⽣⼀个新的函数作⽤域
- 在函数作⽤域中定义的变量,都是局部变量,它只能在函数内部被访问
3.3 示例
a =1 #全局作用域,任何地方都可以调用
b =2
def fun():
c =1 #函数作用域
d =2
print('a=',a)
print('b=',b)
def fun1():
print('c=',c)
print('d=',d)
fun1()
print('c=',c)
print('d=',d)
print(fun())
print('c=', c)
print('d=', d)
'''
Traceback (most recent call last):
File "/Users/mianhua/PycharmProjects/python/Python基础/day09/函数的作用域.py", line 21, in <module>
print('c=', c)
NameError: name 'c' is not defined
a= 1
b= 2
c= 1
d= 2
c= 1
d= 2
None
'''
四、命名空间
- 命名空间实际上就是⼀个字典,是⼀个专⻔⽤来存储变量的字典
- locals()⽤来获取当前作⽤域的命名空间
- 返回值是⼀个字典
- 如果在全局作⽤域中调⽤locals()则获取全局命名空间
a = 1
b = 2
c = 3
def fun():
pass
space =locals()
print(locals())
'''
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7fea62eb5eb0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': '/Users/mianhua/PycharmProjects/python/Python基础/day09/命名空间.py', '__cached__': None, 'a': 1, 'b': 2, 'c': 3, 'space': {...}}
'''
- 如果在函数作⽤域中调⽤locals()则获取函数命名空间
def fun():
a = 1
b = 2
c = 3
space = locals()
print(locals())
pass
fun()
'''
{'a': 1, 'b': 2, 'c': 3, 'space': {...}}
'''
五、递归函数
5.1 概念
递归是解决问题的⼀种⽅式,它的整体思想,是将⼀个⼤问题分解为⼀个个的⼩问题,直到问题⽆法分解时,再去解决问题
5.2 递归式函数有2个条件
- 1.基线条件 问题可以被分解为最⼩问题,当满⾜基线条件时,递归就不执⾏了
- 2.递归条件 可以将问题继续分解的条件
5.3 举例
求10!的值
#思路:10!=109!=1098!=109*8…1 n(n-1)
def fun(n): #求n!的值
if n == 1:
return 1
return n * fun(n-1)
print(fun(10))
'''
3628800
'''
5.4 拓展
求1+2!+3!+…+n!
已知n!,可以把1到n每个阶乘的值存入列表,然后列表内的值求和
def fun(n):
if n == 1:
return n
return n * fun(n - 1)
list1 = []
def num_list(n):
for i in range(1, n + 1):
list1.append(fun(i))
print(list1)
return list1
def sum(n):
total = 0
num_list(n)
for i in range(n):
total += list1[i]
return total
print(sum(20))
'''
[1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600, 6227020800, 87178291200, 1307674368000, 20922789888000, 355687428096000, 6402373705728000, 121645100408832000, 2432902008176640000]
2561327494111820313
'''
六、作业
6.1 闰年判断
用函数实现一个判断用户输入的年份是否是闰年的程序
- 能被400整除的年份
- 能被4整除,但是不能被100整除的年份
- 以上2种方法满足一种即为闰年
i
mport random
def leap_year():
if year % 400 == 0:
print('{}年 是 闰年'.format(year))
elif year % 4 == 0 and year %100 != 0:
print('{}年 是 闰年'.format(year))
else:
print('{}年 不是 闰年'.format(year))
def random_year():
global year
year = random.randint(1000,5000)
#print('随机年份',year)
'''
3946年 不是 闰年
2000年 是 闰年
2072年 是 闰年
3201年 不是 闰年
2841年 不是 闰年
1949年 不是 闰年
3650年 不是 闰年
1408年 是 闰年
3383年 不是 闰年
1989年 不是 闰年
'''
6.2 猴子吃桃问题(递归) :
猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个。第二天早上 又将剩下的桃子吃掉一半,
又多吃了一个。以后每天早上都吃了前一天剩的一半零一 个。到第10天早上想再吃时,见只剩下一个桃子了,求第一天共摘了多少桃子?
6.2.1 递归
#@author:mianhua
#@Time:2021/4/30
#@File:作业2.py
#@Describition:计算猴子吃桃问题
#猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个。第二天早上又将剩下的桃子吃掉一半, 又多吃了一个。以后每天早上都吃了前一天剩的一半零一个。到第10天早上想再吃时,见只剩下一个桃子了,求第一天共摘了多少桃子?
#思考:
#规律 第一天的数量等于 第二天的数量+1再乘以2
#fun(1)=(fun(1+1)+1)*2
#基准条件:第十天 有一个 fun(10)=1
def fun(n):# 求第一天共摘了多少桃子 fun(1)
if n==10: #基准条件
return 1
else:
return (fun(n+1)+1)*2 #递归条件:
#分解
for i in range(10,1,-1):
print("第{}天,还剩{}个桃子".format(i,fun(i)))
print("第1天一共有{}个挑子".format(fun(1)))
'''
第10天,还剩1个桃子
第9天,还剩4个桃子
第8天,还剩10个桃子
第7天,还剩22个桃子
第6天,还剩46个桃子
第5天,还剩94个桃子
第4天,还剩190个桃子
第3天,还剩382个桃子
第2天,还剩766个桃子
第1天一共有1534个挑子
'''
6.2.2 For循环
num = 1
print('第10天有1个桃子')
for i in range(9,0,-1):
num=(num+1)*2
print('第',i,'天有',num,'个桃子')
'''
第10天有1个桃子
第 9 天有 4 个桃子
第 8 天有 10 个桃子
第 7 天有 22 个桃子
第 6 天有 46 个桃子
第 5 天有 94 个桃子
第 4 天有 190 个桃子
第 3 天有 382 个桃子
第 2 天有 766 个桃子
第 1 天有 1534 个桃子
'''
6.2.3 while循环
i = 10
num = 1
while i>1:
num=(num+1)*2
i-=1
print('第{}天有{}个桃子'.format(i,num))
'''
第9天有4个桃子
第8天有10个桃子
第7天有22个桃子
第6天有46个桃子
第5天有94个桃子
第4天有190个桃子
第3天有382个桃子
第2天有766个桃子
第1天有1534个桃子
'''
七,额外的思考
- 1.“递归”包括两个过程:“递”的过程,“归”的过程!
- 2.基线条件可以理解为,“递”和“归”的转折点,且这个转折点一定是有一个明确的定义的
- 3.递归条件可以理解为,“递”和“归”的方式,
比如作业题2,已知第10天的值,求第一天,起点是1,转折点上是10,这是一个累加的过程
可以做这样一个函数
def fun(n):
print('第,n,天,递')
if n<10:
fun(n+1)
print('第,n,天,归')
fun(1)
'''
#数据的传输过程如下
1 递
2 递
3 递
4 递
5 递
6 递
7 递
8 递
9 递
10 递
10 归
9 归
8 归
7 归
6 归
5 归
4 归
3 归
2 归
1 归
'''
第10天早上想再吃时,见只剩下一个桃子了 可以确定转折点是
if n==10:
return 1
第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个
第一天n就等于第二天(n+1)在加上1再乘以2
(fun(n+1)+1)*2
def fun(n):
# print('第,n,天,递')
if n==10:
return 1
return (fun(n+1)+1)*2
#print('第,n,天,归')
print(fun(1))