Python学习笔记(九)——函数返回值,作用域,递归

函数的返回值

  • 返回值就是函数执行以后返回的结果
  • 通过return来指定函数的返回值
  • return后面可以跟任意对象,返回值甚至可以是一个函数
def fun(a, b, c):
    if a > b and a > c:    # a 最大
        result = 'a+b+c=%d' %(a + b + c)
    elif b > a and b > c:    # b 最大
        result = [f'a={a}', f'b={b}', f'c={c}']
    elif c > a and c > b:    # c 最大
        result = {'a': a, 'b': b,'c': c}
    else:    # 最大值不唯一
        result = {a, b, c}
    return result

result = fun(9,5,3)
print(result)
# 字符串:a+b+c=17
result = fun(3,9,5)
print(result)
# 列表:['a=3', 'b=9', 'c=5']
result = fun(3,5,9)
print(result)
# 字典:{'a': 3, 'b': 5, 'c': 9}
result = fun(4,7,7)
print(result)
# 集合:{4, 7}
文档字符串
  • help()是Python中内置函数,通过help()函数可以查询Python中函数的用法
  • 在定义函数时,可以在函数内部编写文档字符串,文档字符串就是对函数的说明
def fun(a, b, c):
    '''
    # 在函数内第一行输入三个引号后,按回车,pycharm会自动生成对函数解释的文档
    :param a: 
    :param b: 
    :param c: 
    :return: 
    '''

函数的作用域

作用域(scope)

作用域指的是变量生效的区域,在Python中一共有两种作用域

  1. 全局作用域
    • 全局作用域在程序执行时创建,在程序执行结束时销毁
    • 所有函数以外的区域都是全局作用域
    • 在全局作用域中定义的变量,都是全局变量,全局变量可以在程序的任意位置进行访问
a = 1    # 在函数外定义的变量作用域为全局作用域(全局变量),可以在该文件下的函数内被引用
def fun1():
	print('a+1=',a+1)    # 可以在函数内引用全局变脸,但不能修改全局变量,如:a += 1,会报错
	b = a + 2    # 函数内部定义的变量作用域为函数作用域(局部变量),不能在该函数外被引用
	print('b=', b)
	def fun2():    # 函数内部又定义的函数是内部函数,也叫嵌套函数
		c = a + b + 3    # 内部函数可以引用外层函数的函数作用域变量(b)
		print('a+b+3=',c)
	return fun2    
'''
如果想通过外层函数调用内部函数,就要在外层函数返回内层函数名,
之后再给调用的外层函数赋值,然后调用这个赋值的函数,方法如下:
'''
result = fun1()    # 这里调用fun1,并将返回值赋值给result,此时result=fun2
# a+1= 2
# b= 3
result()    # 这里调用result(),相当于fun2()
# a+b+3= 7
print(a)    # 最后发现,经过函数的计算,全局变量a的值并没有发生改变
# 1
  1. 函数作用域
    • 函数作用域在函数调用时创建,在调用结束时销毁
    • 函数每调用一次就会产生一个新的函数作用域
    • 在函数作用域中定义的变量,都是局部变量,它只能在函数内部被访问
  2. 内部函数: 定义在函数内部的函数
    • 内部函数可以访问外部函数的局部变量
    • 内部函数可以修改外部函数的可变类型的变量,如list
    • 内部函数修改全局不可变变量时,需要在内部函数中声明:global 变量名
    • 内部函数修改外部函数的不可变变量时,需在内部函数中声明:nonlocal 变量名
a = 1
def fun1():
	# 如果想要用全局变量并重新赋值,需要用 global
	global a
	a += 1
	print('a+1=', a+1)
	b = a + 2
	print('b=', b)
	print('a=', a)

	def fun2():
		global a    # 内层函数如果想改变全局变量,需要再次使用 global 将全局变量转化
		nonlocal b    # 如果内层函数想要使用外层函数定义过的变量,需要在变量前加 nonlocal
		a += 1
		b += 2
		c = a + b + 3
		print('c=', c)
		print('b=', b)
		print('a=', a)

	return fun2

result = fun1()
# a+1= 3
# b= 4
# a= 2
result()
# c= 12
# b= 6
# a= 3
print(a)    # 最后发现,经过函数的计算,全局变量a的值被改变
# 3

命名空间

命名空间实际上就是一个字典,是一个专门用来存储变量的字典

  • locals()用来获取当前作用域的命名空间
  • 如果在全局作用域中调用locals()则获取全局命名空间
  • 如果在函数作用域中调用locals()则获取函数命名空间
  • 返回值是一个字典
a = 1
def fun1():
    b = a + 2
    print(locals())    # {'b': 3} 这里尽管引用了全局变量a,也不会显示a
    return b
result = fun1()
print(result)    # 3
print(locals())
"""
{'__name__': '__main__', '__doc__': None, '__package__': None, 
'__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x00000210A7BDB128>, 
'__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 
'__file__': 'D:/python/腾讯课堂笔记作业/作业/201202/课堂笔记.py', '__cached__': None, 'a': 1, 
'fun1': <function fun1 at 0x00000210A7CA7BF8>, 'result': 3}
"""
a = 1
def fun1():
    global a
    a += 1
    b = a + 2
    print(locals())    # {'b': 4} 这里虽然可以对a进行重新赋值,但a依然不是局部变量
    return f'b={b}, a={a}'
result = fun1()
print(result)    # b=4, a=2

递归函数

递归是解决问题的一种方式,它的整体思想,是将一个大问题分解为一个个的小问题,直到问题无法分解时,在去解决问题

  • 递归式函数有2个条件
  1. 基线条件 问题可以被分解为最小问题,当满足基线条件时,递归就不执行了
  2. 递归条件 可以将问题继续分解的条件
下面以典型的递归函数——求阶乘来距举例:
def my_factorial(n):    # 函数是求n的阶乘:n!
	if n == 1:
	# 基线条件:当n=1时,阶乘为1
		return 1
	# 递归条件:n*(n-1)!
	return my_factorial(n-1)*n

result = my_factorial(10)    # 求10的阶乘
print(result)     # >>> 3628800

第九讲作业

  1. 用函数实现一个判断用户输入的年份是否是闰年的程序
    提示:
    1.能被400整除的年份
    2.能被4整除,但是不能被100整除的年份
    以上2种方法满足一种即为闰年
def leap_year(user_year):
    if user_year.isdigit() and len(user_year) == 4:    # 先判断输入的是否为年份
        user_year = int(user_year)
        if user_year % 400 == 0:    # 能被400整除
            print("你输入的是闰年!")
        elif user_year % 100 != 0 and user_year % 4 == 0:    # 不能被100整除,但能被4整除
            print('你输入的是闰年!')
        else:
            print('你输入的不是闰年!')
    else:
        print('你输入的不是年份!')


user_year = input('请输入年份:')
leap_year(user_year)
  1. 猴子吃桃问题(递归):
    猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个。
    第二天早上又将剩下的桃子吃掉一半,又多吃了一个。
    以后每天早上都吃了前一天剩的一半零一个。
    到第10天早上想再吃时,见只剩下一个桃子了,求第一天共摘了多少桃子?
  • 分析题目:
    这里用反向推导,求猴子可以吃桃子的个数
    吃1天 —— 第十天:1个桃子
    吃2天 —— 第九天:(第10天的桃子数+1)*2
    吃3天 —— 第八天:(第9天的桃子数+1)*2

    吃8天 —— 第二天:(第3天的桃子数+1)*2
    吃9天 —— 第一天:(第2天的桃子数+1)*2
def peaches_num(days):  
    # 函数peaches_num表示吃桃子的数量,days表示一共吃了多少天
    # 基线条件:
    if days == 1:
        peaches = 1
        return peaches
    # 递归条件:
    return (peaches_num(days - 1) + 1) * 2    # 后一天吃桃子的数量等于(前一天吃桃子数+1)*2


result = peaches_num(9)
print(f'第一天一共摘了{result}个桃子')
  • 计算结果为:第一天一共摘了1534个桃子
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值