函数用法
函数的参数类型
不可变类型参数:数值型、字符串str、元组tuple。
可变类型:列表list,字典dict
函数中a不可变,fun(a)内部修改 a 的值,只是修改另一个复制的对象,不会影响 a 本身。
1、传递不可变类型参数,不会影响参数本身
2、传递可变类型参数,会影响参数本身
# 不可变参数类型
a =1 print(id(a)) # 2009628784 def func(a): a= 10 print(a,id(a)) func(a) # 20 2009629392 def func(a): a= 1 print(a,id(a)) func(a) # 1 2009628784 print(a,id(a)) # 1 2009628784
# 可变参数类型 b=[10,20] print(id(b)) #2324968580360 def func(b): b.append(30) print(id(b)) func(b) #2324968580360 print(b,id(b)) # [10, 20, 30] 2324968580360
函数参数(必选参数、默认参数,可选参数、关键字参数)
# 必选参数 def func1(x): return x*x func1(2) #4 #默认参数, #注意:默认参数必须放到必选参数之后
#缺陷:
def funcx(L=[]): L.append("The End" return L
funcx()
# 在函数定义时,默认参数L所制定的地址已经确定。每次调用都会改变L的内容
def func2(x,y=10): return x*y func2(3) # 30 func2(3,5) # 15
可选参数
def func3(*nmbers):
sum = 0
for i in numbers:
sum = sum+i*i
return sum
func3([1,2,3])
# 14
关键字参数
def func4(name,**kwargs):
print("data:",kwargs)
递归函数
递归函数 如果一个函数在内部调用自身本身,这个函数就是递归函数。
使用递归函数的条件:
1. 必须留出口
2. 自己调用自己
case1:
# 使用递归函数求 1*2*3....*7*8*9*10 def func(x): if x==1: return x return x*func(x-1) print(func(10)) #3628800
case2:
# 将列表全部展开
lst1 = [1,2,[3,4,[5,[6,[7],8,9]],10],11,12,13] lst2 =[] def func(lst1): for i in lst1: if isinstance(i,list): # 如果是列表就执行func(i) func(i) else: lst2.append(i) # 如果不是就把元素放到lst2列表中 func(lst1) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,13]
case3:
# 使用递归函数求斐波拉契数列
#1 1 #2 2 #3 2+1=3 #4 3+2 = 5 #... #n f(n-1)+f(n-2) def func(n): if n==1 or n==2: return n return func(n-1)+func(n-2) print(func(5)) # 8
case3:
青蛙一次能跳1个或3个或7个或10个台阶,问:有n个台阶,青蛙跳上去有几种跳法? 1-2 1 n<=2 f(n)=1 3 2 f(2)+f(0)=2 4 2+1=3 f(3)+f(1)=4 5 3+1=4 6 4+2=6 ... n f(n-1)+f(n-3)+f(n-7)+f(n-10) def func(x): if 1<=x<3: return 1 elif x<0: return 0 else: return func(x-1)+func(x-3)+func(x-7)+func(x-10) print(func(10)) #22
函数的命名空间
命名空间一共分为三种:局部命名空间、全局命名空间、内置命名空间
局部命名空间:每个函数都有自己的命名空间,叫做局部空间,它记录了函数的变量,包括函数的参数和局部定义的变量
def test(): a =2 print(a) test() print(a) #2 #NameError: name 'a' is not defined
全局命名空间:每个模块拥有它自已的命名空间,叫做全局命名空间,它记录了模块的变量,包 括函数、类、其它导入的模块。
a=2 def test(): print(a) test() print(a) #2 #2
内置命名空间:任何模块均可访问它,它存放着内置的函数和异常。
print(),input()...
局部变量和全局变量
局部变量:定义在函数内部的变量
全局变量:定义在函数外部的变量,如果是不可变类型,则在函数内部不可以被修改
name='zzq' list1=[10] def func(): name='johnson' list1.append(name) print("inner",name) func() print("outer",name) print(list1) #inner johnson # outer zzq name ='zzq' name ='johnson' def func(): global name #全局变量 name='123' func() print(name) # 123 name = 'zzq' def func1(): name='ls' def func2(): nonlocal name # 在函数本地作用域找不到变量的情况下,解释器会自动在外层函数寻找 name='abc' func2() print("---------",name) func1() print(name)
- 函数定义了本地作用域,而模块定义的是全局作用域。
如果想要在函数内定义全局作用域,需要加上global修饰符。- 变量名解析:LEGB原则
当在函数中使用未认证的变量名时,Python搜索4个作用域[本地作用域(L)(函数内部声明但没有使用global的变量),之后是上一层结构中def或者lambda的本地作用域(E),之后是全局作用域(G)(函数中使用global声明的变量或在模块层声明的变量),最后是内置作用域(B)(即python的内置类和函数等)]并且在第一处能够找到这个变量名的地方停下来。如果变量名在整个的搜索过程中
都没有找到,Python就会报错。- 转载于https://www.cnblogs.com/summer-cool/p/3884595.html