![](https://i-blog.csdnimg.cn/blog_migrate/f72f15d4cb4f2c3eb2fdbf7d299f87d8.png)
一、函数的基本类型
![](https://i-blog.csdnimg.cn/blog_migrate/56283365697f8f545f203528bf7f7510.png)
二、局部变量
局部变量:就是在函数内部定义的变量【作用域仅仅局限在函数的内部】
其实在我看来,你在哪个函数中定义的的,这个变量的有效区域就是在哪个函数中
![](https://i-blog.csdnimg.cn/blog_migrate/c7be3a479c25ac69be545e7a94ba3d7d.png)
eg:就类似于我家有money,你家也有money,但是我家的money你肯定不能使用呀,你使用了不就是抢劫了嘛
'''
不同的函数可以定义相同名字的局部变量,但是各自用各自的,互相不产生影响
局部变量的作用:为了临时的保存数据,需要在函数中定义来进行存储
'''
def printInfo():
name='linran'#这里的name是属于printInfo的局部变量
print(name)
pass
def TestMethod():
name='linran2'#这里的name是属于TestMethod的局部变量
print(name)
pass
三、全局变量
1.什么是全局变量
就类似于班级中用班费购买的体温枪,你可以使用,我也可以使用,那么这个体温枪就类似于全局变量
![](https://i-blog.csdnimg.cn/blog_migrate/f51d400e9c222277a7b2b0a2b3c12f1f.png)
eg:
major='计算机科学与技术'#这里的Major就是一个全局变量
def printInfo():
name='linran'#这里的name是属于printInfo的局部变量
print('{}:{}'.format(name,major))#你可以使用
pass
def TestMethod():
name='linran2'#这里的name是属于TestMethod的局部变量
print('{}:{}'.format(name,major))#我也可以使用
pass
promble:如果定义了一个全局变量name,然后又在函数中定义了一个局部变量,那么系统是使用哪个变量呢?
eg:
major='计算机科学与技术'#这里的Major就是一个全局变量
name='林然老师'
def printInfo():
name='linran'#这里的name是属于printInfo的局部变量
print('{}:{}'.format(name,major))#你可以使用
pass
def TestMethod():
name='linran2'#这里的name是属于TestMethod的局部变量
print('{}:{}'.format(name,major))#我也可以使用
pass
printInfo()
TestMethod()
结果:
![](https://i-blog.csdnimg.cn/blog_migrate/a561e3b7ccf8a24c535fe33f98bd8c10.png)
其实当全局变量和局部变量出现重复定义时,程序会优先使用函数内部的变量;就类似于省考试院发布一项归档,市考试院发布同样一项规定,那么你所在的市肯定是执行自己的规定呀
2.如何修改全局变量
如果要想在函数内部对全局变量进行修改,需要使用global关键字,引用时是不需要的,就是直接拿来使用即可
major='计算机科学与技术'#这里的Major就是一个全局变量
name='林然老师'
def changeGlobDate():
global name #在这里声明自己是引用的全局变量
name='lin'
pass
print(name)
changeGlobDate()
print(name)
结果:
![](https://i-blog.csdnimg.cn/blog_migrate/b2aec15b2678636c63282a462c4bfd14.png)
四、函数参数引用传值
![](https://i-blog.csdnimg.cn/blog_migrate/125e3af7bb3f0edc4fcf31e3bd4bf30a.png)
![](https://i-blog.csdnimg.cn/blog_migrate/3d06d93355b6051651589d577b2d58ff.png)
eg:
a=1
def func(x):
print('x的地址{}'.format(id(x)))
x=2
print('修改后x的地址{}'.format(id(x)))
pass
print('a的地址{}'.format(id(a)))
#调用函数
func(a)
![](https://i-blog.csdnimg.cn/blog_migrate/f5c185ebb9f6bffded4f70e6e7681d88.png)
我们可以看到a和x绑定是同一个对象,就是对同一个内存地址的引用,x修改后,x就绑定到了另外一个对象,但是对于a来说为什么没有发生变化呢?
我们来复习一个概念:
不可变类型:数值型、字符串、元组等
可变类型:字典、列表等
如果我们传递的参数是一个列表【可变类型】,我们在函数内部对形参进行修改,实参是否改变呢?
list1=[1,2,3,4]
def func(x):
print('x{}的地址{}'.format(x,id(x)))
x.append(5)
print('修改后x:{}的地址{}'.format(x,id(x)))
pass
print('list1:{}的地址{}'.format(list1,id(list1)))
#调用函数
func(list1)
![](https://i-blog.csdnimg.cn/blog_migrate/5812be7ea7137dccc6643ab71aef48a8.png)
我们发现对于可变类型参数,当对形参进行修改时,实参也会随之发生变化,就相当于形参就是实参本身;
小结:
在python中,万物皆对象,在函数调用的时候,实参传递的就是对象的引用
了解了原理后,就可以更好的去把控在函数内部的处理是否会影响到函数外部的数据变化
参数传递是通过对象引用来完成的
五、匿名函数
- 什么是匿名函数:其实就是没有名字的函数
语法:lambda 参数1,参数2,参数3: 执行代码语句
特点:使用lambda关键字去创建函数,没有名字的函数,
匿名函数冒号后面的表达式有且只有一个,注意,后面只是表达式,不是语句,
而且匿名函数自带return,其返回的值就是表达式的值
3.缺点:lambda只能是单个表达式,不是一个代码块,lambda的设计就是为了满足简单函数的场景,仅仅只能封装有限的逻辑,如果是复杂的逻辑还是使用def标准函数进行使用
![](https://i-blog.csdnimg.cn/blog_migrate/93805bfe678d0ddf38b1b8d77ed2611d.png)
eg1:
def computer_add(x,y):
'''
普通函数
:param x:
:param y:
:return:
'''
return x+y
print('普通函数',computer_add(15,36))
M=lambda x,y:x+y #匿名函数,通过一个变量去接收匿名函数,然后通过变量去调用
print('匿名函数',M(22,19))
![](https://i-blog.csdnimg.cn/blog_migrate/05a0544fbfed610e22b1c00bf50a3c24.png)
2、三元运算符:
![](https://i-blog.csdnimg.cn/blog_migrate/55f903aa21ba498ec4386d3a779c8d94.png)
eg:
result=(lambda age: '可以参军' if age>=18 else '不可以参军')
print(result(18))
#result=(lambda age: '可以参军' if age>=18 else '不可以参军')(18)
#print(result) 这种是直接调用
结果:
![](https://i-blog.csdnimg.cn/blog_migrate/bf4f2add0e4e08e8d336ff526b55102a.png)
六、递归函数
1.什么是递归函数
![](https://i-blog.csdnimg.cn/blog_migrate/1fd05a99bd546d2972116582777dbd82.png)
#求阶乘
#利用循环方式实现
def jiecheng(n):
result=1
for item in range(1,n+1):
result*=item
return result
print('循环方式10的阶乘',jiecheng(10))
#递归的方式实现
def digui(n):
'''
递归方式实现阶乘计算
:param n:
:return:
'''
if n==1:#出口判断
return 1
else:
return n*digui(n-1)#递归表达式
print('递归方式实现10的阶乘',digui(10))
![](https://i-blog.csdnimg.cn/blog_migrate/0756a5e9078fd31ac04d57c28d6b70b0.png)
2.递归满足的条件
自己调用自己,也就是递归表达式
必须要有出口,也就是明确的结束条件
优点:逻辑简单,定义简单
缺点:容易导致栈【内存空间】溢出,也就是内存资源紧张,甚至内存泄漏,因为是一层一层调用的
3.案例:模拟实现树形结构文件查找遍历
import os #引入文件操作模块
def Find_file(file_Path):
listRs=os.listdir(file_Path)#得到该路径下面的文件夹或文件
for file_item in listRs:
full_path=os.path.join(file_Path,file_item)#获取完整的文件路径
if os.path.isdir(full_path):#判断是否是文件夹
Find_file(full_path) #如果是文件夹,就再次递归
else:
print(file_item)#否则那么就是文件,直接输出文件名
pass
pass
else:
return
pass
#调用搜索文件对象
Find_file('E:\互联网+')
![](https://i-blog.csdnimg.cn/blog_migrate/5d24a0c1b0472fd04ad4df003e9a2676.png)
这是我的一个文件夹
![](https://i-blog.csdnimg.cn/blog_migrate/09d681df7355a8a7a12551f665bafc7f.png)
得到的输出结果:
![](https://i-blog.csdnimg.cn/blog_migrate/f3ccc4b9dc32e7e7f9c80a8fa10ff2af.png)
4.递归函数优缺点
![](https://i-blog.csdnimg.cn/blog_migrate/355d73750214d24039cbfc8ac620026d.png)
七、小结
![](https://i-blog.csdnimg.cn/blog_migrate/2467a526da041627c0a652f9f548d0e3.png)