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 闰年判断

用函数实现一个判断用户输入的年份是否是闰年的程序

  1. 能被400整除的年份
  2. 能被4整除,但是不能被100整除的年份
  3. 以上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==10return 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))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MIANHUA_007

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值