1.函数的返回值
- 返回值就是函数值执行返回的结果
- 通过return来指定函数返回的结果
- return后面可以是任意对象,返回值是甚至可以是一个函数
#整数
def fn():
return 100
r=fn()
print(r) #100
print(fn())#100
#字符串
def fn():
return 'python'
r=fn()
print(r) #python
print(fn())
#列表
def fn():
return [1,2,3]
r=fn()
print(r) #[1, 2, 3]
print(fn())
#字典
def fn():
return {'name':'hhhh'}
r=fn()
print(r) #{'name': 'hhhh'}
print(fn()) #{'name': 'hhhh'}
#函数
def fn():
def fn2():
print('hello')
return fn2
r=fn() #<function fn.<locals>.fn2 at 0x0000022A0201BB70>
r() #hello
print(r) #[1, 2, 3]
- 在函数中 return后面的代码都不会执行,return一旦执行函数自动结束
def fn4():
for i in range(5):
if i==3:
break
print(i)
print('循环完毕')
fn4()
#0
#1
#2
#循环完毕
def fn4():
for i in range(5):
if i==3:
return
print(i)
print('循环完毕')
fn4()
#0
#1
#2
- 如果仅仅写一个return,或者不写return,则相当于return None
def fn2():
return
r = fn2()
print(r)#None
def fn3():
print('hhh')
print('123')
r=fn3()
print(r)
#hhh
#123
#None
def fn3():
print('hhh')
return
print('123')
r=fn3()
print(r)
#hhh
#None
fn是函数对象
fn()是在调用函数
def fn5():
return 100
# fn5和fn5()的区别
print(fn5)#<function fn5 at 0x00000227474BBAE8>
print(fn5())#100
2.文档字符串
- help()是python中内置函数,通过help()函数可以查询python中函数的用法
#help()函数
help(print)
print('www','baidu','com')#www baidu com
print('www','baidu','com',sep='.')#www.baidu.com
- 在定义函数时,可以在函数内部编写文档字符串,文档字符串就是对函数的说明
#自定义函数
def fn(a,b,c):
'''
:param a:
:param b:
:param c:
:return:
'''
return 1
help(fn)
#fn(a, b, c)
#:param a:
#:param b:
#:param c:
#:return:
def fn(a:bool,b:int,c:str)->int:
'''
:param a:
:param b:
:param c:
:return:
'''
return 1
help(fn)
#fn(a:bool, b:int, c:str) -> int #(返回整数类型)
#:param a:
#:param b:
#:param c:
#:return:
3.函数的作用域
-
作用域(scope)
-
作用于是指变量生效的区域
-
在python中一共有两种作用域
全局作用域
-
全局作⽤域在程序执⾏时创建,在程序执⾏结束时销毁
-
所有函数以外的区域都是全局作⽤域
-
在全局作⽤域中定义的变量,都是全局变量,全局变量可以在程序的任意 位置进⾏访问
函数作用域 -
函数作⽤域在函数调⽤时创建,在调⽤结束时销毁
-
函数每调⽤⼀次就会产⽣⼀个新的函数作⽤域
-
在函数作⽤域中定义的变量,都是局部变量,它只能在函数内部被访问
def fn():
a=10
print('函数内部:''a=',a)#函数内部:a= 10
fn()
#print('函数外部:''f=',f)#NameError: name 'f' is not defined
f=20
def fn():
a=10
print('函数内部:''a=',a)#函数内部:a= 10
print('函数内部:''f=', f) #函数内部:f= 20
fn()
print('函数外部:''f=',f) #函数外部:f= 20
def fn2():
a=30
def fn3():
print('这是fn3中','a=',a) #这是fn3中 a= 30
fn3()
fn2()
修改全局变量:
如果希望在函数内部修改全局变量,则使用global关键字,来声明变量
global a 声明在函数内部的使用(修改全局变量)
a=20
def fn3():
global a #声明在函数内部的使用(修改全局变量)
a=40
print('函数内部','a=',a)
fn3()
print('函数外部','a=',a)
#函数内部 a= 40
#函数外部 a= 40
a = 50
def fn():
a = 10 # 这个不会被改
print('fn',a)
def fn2():
global a
a = 20
print('fn2',a)
fn2() #fn2 10
fn() # fn 20
print(a) # 20
fn() # fn 20
#fn 10
#fn2 10
#20
#fn 10
#fn2 10
4. 命名空间 (了解)
-
命名空间实际上就是⼀个字典,是⼀个专⻔⽤来存储变量的字典
-
locals()⽤来获取当前作⽤域的命名空间
-
如果在全局作⽤域中调⽤locals()则获取全局命名空间,如果在函数作⽤域中 调⽤locals()则获取函数命名空间
s['h']=100
print(h)
#100 字典中关键字c 直接就插入了呀
def fn4():
s=locals()#获取函数内部命名空间
print(s)#{}
fn4()
def fn4():
a=10
s=locals()#获取函数内部命名空间
s['b']=20
print(s)#{'a': 10, 'b': 20}
fn4()
内部获取全局的命名空间
-
返回值是⼀个字典
5.递归函数 -
递归是解决问题的⼀种⽅式,它的整体思想,是将⼀个⼤问题分解为⼀个个 的⼩问题,直到问题⽆法分解时,在去解决问题
-
递归式函数有2个条件
基线条件
问题可以被分解为最⼩问题,当满⾜基线条件时,递归就不 执⾏了
递归条件
可以将问题继续分解的条件
# 尝试求10的阶乘(10!)
# 1! = 1
# 2! = 1*2 = 2
# 3! = 1*2*3 = 6
# .....8*9*10 = 3628800
print(1*2*3*4*5*6*7*8*9*10)#3628800
n=10
for i in range(1,10):
n*=i
print(n) #3628800
#求任意数的阶乘
def fn1(n):
result=n
for i in range(1, n):
result *= i
return result
print(fn1(10)) #3628800
#递归
def fn2(n):
#基数条件
if n==1:
return 1
#递归条件
return n*fn2(n-1)
print(fn2(10))#3628800
def fn2(n):
if n==1:
return 1
return n*(n-1)
print(fn2(10))#90
递归练习
#练习
#创建一个任意数的任意幂运算
# n 幂运算的数字 i 幂运算的次数
# 10**6 = 10 * 10**5
# 10**5 = 10 * 10**4
# 10**4 = 10 * 10**3
# 10**3 = 10 * 10**2
# ......
# 10**1 = 10
def fn2(n,i):
if n==1:
return n
return n*n**(i-1)
print(fn2(5,5)) #3125
def fn5(n,i):
if i==1:
return n
return n*fn5(n,i-1)
print(fn5(5,5))#3125
# 定义一个函数用来检测一个任意字符是否是回文字符
# 如果是返回True,如果不是返回False
# 回文字符串,字符串从前往后念和从后往前念是一样的
# 例如 abcba
# abcdefgfedcba
# 先检查第一个字符和在最后一个字符是否一致,
# 如果不一致一定不是回文字符串
# 如果一致就要检查剩余的部分是不是回文字符串
#以此类推
# bcdefgfedcb 是不是回文
# cdefgfedc
# defgfed
# efgfe
# fgf
# g
def fn2(s):
# 参数s就是要检查的字符串
# 1.基线条件
# 字符串的长度小于2 则字符串一定是个回文(g)
if len(s)<2:
return True
# # 第一个字符和最后一个字符不相同,则一定不是回文字符串
elif s[0] != s[-1]:
return False
# 2.递归条件
return fn2(s[1:-1])
print(fn2('abcdefgfedcba'))
6.作业
汉诺塔游戏,现在有ABC三根柱⼦。
要求:将A柱所有的圆盘放到C柱。在移动 的过程中可以借助B柱。并且规定⼤圆盘不能放⼩圆盘上⾯,每次只能移动⼀个 盘⼦。⽤递归的⽅式来解决汉诺塔问题
# 1.如果只有一个盘子 A --> C
# 2.如果盘子大于等于2的情况下 我们总是可以看成是2个盘子 一个是最下面的盘子和最上面的一个或者是所有的盘子
# 2.1 先把最上面的盘子 A --> B
# 2.2 把最下面的盘子 A --> C
# 2.3 把B柱上的盘子 B --> C
# 定义一个函数解决汉诺塔问题
def hannuoTower(num,a,b,c):
# 参数 num 代表的是盘子 a b c分别代表的是A柱 B柱 C柱
# 第一个条件 基线条件
# 如果只有一个盘子 A --> C
if num == 1:
print('第 1 个盘子从',a,'->',c)
else:
# 第二个条件 递归条件
# num >= 2的情况
# 2.1 先把最上面的盘子 A --> B 借助C柱 num-1 除去最下面的那个盘子
hannuoTower(num-1,a,c,b)
# 2.2 把最下面的盘子 A --> C
print('第',num,'个盘从',a,'->',c)
# 2.3 把B柱上的盘子 B --> C
hannuoTower(num-1,b,a,c)
hannuoTower(3,'A','B','C')
总结