# 无参数 无返回值:一般用于提示信息打印
def pyprint():
print('-'*20)
# 无参数 有返回值:多用于数据采集中,比如获取系统信息
def pycpu():
return info
# 有参数 无返回值:多用在设置某些不需要返回值的参数设置
def set(a):
pass
# 有参数 有返回值:一般是计算型的,需要参数,最终也要返回结果
def caal(a,b):
return c=a+b
二、局部变量和全局变量
根据作用域的不同,分为局部变量和全局变量
1. 局部变量:在函数内部定义的变量,其作用域仅仅局限在该函数内部
局部变量的作用:为了临时的保存数据,需要在函数中定义来进行储存
不同的函数 可以定义相同的局部变量,但是各自用各自的,不会相互产生影响,例如:
def printINfo():
name='Peter'
print('{}'.format(name))
pass
def printInfo2():
name='刘德华'
print('{}'.format(name))
pass
# 两个name没有冲突
2. 全局变量:
当全局变量和局部变量出现重复时,程序有限执行使用函数内部定义的局部变量【地头蛇】
#以下两个是全局变量
Pro='计算机'
name='吴老师' #当全局变量和局部变量都存在时,函数使用局部变量---强龙不压地头蛇
def printInfo():
name='Peter'
print('{}的专业是{}'.format(name,Pro))
pass
def printInfo2():
name='刘德华'
print('{}的专业是{}'.format(name,Pro))
pass
printInfo()
printInfo2()
# 输出
# Peter的专业是计算机
# 刘德华的专业是计算机
如果在函数的内部,想对全局变量进行修改的话,必须使用global关键字进行声明
Pro='计算机'
def chengeGlobal():
'''
要修改全局变量
:return:
'''
Pro='市场营销' #局部变量,跟外部没有关系,不能修改全局变量
pass
chengeGlobal()
print(Pro) #看全局变量 Pro被修改了吗? 没有
printInfo() #上一个代码块的函数
printInfo2() #上一个代码块的函数
# 输出
# 计算机
# Peter的专业是计算机
# 刘德华的专业是计算机
#全局变量 Pro被修改了吗? 并没有,说明局部变量的改变并不能影响全局变量,要怎么修改全局变量呢??
def chengeGlobal():
'''
要修改全局变量
:return:
'''
global Pro #global+要修改的全局变量
Pro='市场营销' #局部变量
pass
chengeGlobal()
print(Pro)
printInfo()
printInfo2()
# 输出(全局变量修改成功)
# 市场营销
# Peter的专业是市场营销
# 刘德华的专业是市场营销
三、python中的引用
a=1
def func(x):
print('x的地址:{}'.format(id(x)))
pass
print('a的地址:{}'.format(id(a)))
func(a)
# x和a的地址一样,是对同一个对象的引用
不可变类型:当修改了变量的值之后,地址就发生改变,此时函数内部变量的修改不会影响外部变量的改变,因为 内部变量的值一旦改变,地址就发生变化,与外部变量所引用地址不同,二者是不同的两个东西。
不可变类型:当该数据类型的对应变量的值发生了改变,那么它对应的内存地址也会发生改变,对于这种数据类型,就称不可变数据类型。
a=1 #不可变类型
def func(x):
print('x的地址:{}'.format(id(x))) #地址与a的地址一样
x=2 #不会改变全局变量的值,但是局部变量的值改变
print('x修改之后的地址:{}'.format(id(x))) #地址变化了,因为该变量是不可变类型,值变化,地址就改变了,所引用的对象发生了改变
pass
print('a的地址:{}'.format(id(a)))
func(a) #输出的是2 的地址
print(a) # 不是把a的1传递过来,是把1这个对象的地址的引用 传递过来
可变类型:由于【地址不会发生改变】【对对象的引用不会发生改变】。由于列表的地址不会修改,那么在函数内部的修改直接会影响到函数外部变量的修改--------函数内部的修改,导致该地址上的值改变,外部变量也是引用的该地址,所以都会发生变化。
可变类型:当该数据类型的对应变量的值发生了改变,那么它对应的内存地址不发生改变,对于这种数据类型,就称可变数据类型。
li=[]
def testRenc(parms):
print(id(parms))
pass
print(id(li))
testRenc(li)
# 也是对同一个地址的引用,但是如果修改一下
li=[]
def testRenc(parms):
li.append([1,3,5,6,7])
print(id(parms))
print('内部的{}'.format(li))
pass
print(id(li))
testRenc(li)
print('外部的变量对象{}'.format(li))
| 数据类型 | 可变/不可变 |
| 整型 | 不可变 |
| 字符串 | 不可变 |
| 元组 | 不可变 |
| 列表 | 可变 |
| 集合 | 可变 |
| 字典 | 可变 |
1. 在python中,所有的东西都是对象,实参传递的就是对象的引用
2. 了解了之后原理,就可以更好的去把控 在函数内部的处理是否会影响到函数外部的数据变化 参数传递是通过对象的引用来完成的、参数传递是通过对象的引用来完成的、参数传递是通过对象的引用来完成的、
四、匿名函数1.使用lambda关键字 创建匿名函数,匿名:没有名字的函数,不需要def关键字创建标准的函数 2.语法结构: lambda 参数1,参数2,参数3:执行代码表达式 3.特点:只用lambda关键字创建函数,没有名字的函数,匿名函数冒号后面的表达式有且只有一个,注意:是表达式,不是语句 4.匿名函数自带return, 而这个return的结果就是表达式计算后的结果 5.缺点:lambda只能是单个表达式,不是一个代码块,lambda的设计只是为了满足简单函数的场景 仅仅能封装有限的逻辑,复杂逻辑实现不了,必须使用def来实现
# 声明:创建好的匿名函数 用一个变量 来接收
M=lambda x,y:x+y #自带return关键字,冒号后面是 表达式
print(M(23,3)) # 调用:通过变量去调用匿名函数(间接调用)
# 另外一种调用方式(直接调用),加括号后再加数值
M=(lambda x,y:x+y)(23,3)
print(M)
Result=lambda a,b,c:a*b*c
print(Result(1,2,3))
# lambda与三元运算符类似的效果
if a:
b
else:
c
# 等效表达式为:b if a else c
# 这样的表达式(三元运算)能够放在lambda中,他们能在lambda函数中来实现逻辑选择
# 选择逻辑 的实现,比较大小,找出较大者或者较小者
G=(lambda x,y:x if x>y else y)
G(3,5)
G(2,4) # 间接调用
rs=(lambda x,y:x if x>y else y)(12,16) #直接调用
print(rs)
#例
age=19
print('可以参军' if age>18 else '继续上学') #可以替代传统双分支的写法
#例
varS=lambda x:(x**2)+890
print(varS(10))
五、递归函数
1. 递归函数:在一个函数内部不调用其他函数, 而是调用自己本身的话,这个函数就是递归函数 2. 优点: 代码整洁、逻辑简单、定义明确 3. 递归可以将任务分解为更简单的子问题, 递归的使用比一些嵌套迭代更容易 4.缺点:容易导致栈溢出,内存资源紧张,甚至内存泄漏 递归逻辑很难调试,递归条件处理不好容易造成程序无法结束,知道达到最大的递归错误 递归占用大量内存, 耗费计算机资源 5. 递归函数必须满足的条件: 必须满足一个【结束条件】,否则会一直递归下去,直到到达最大递归深度报错
#例如:求阶乘5!=5*4*3*2*1
#循环来实现
def jiecheng(n):
result=1
for item in range(1,n+1):
result*=item
pass
return result
print(jiecheng(5))
#用递归函数来实现
def factorial(n):
if n==1:
return 1
return n*factorial(n-1)
print(factorial(5))
或
def digui(n):
if n==1:
return 1
else:
return n*digui(n-1)
pass
# 递归调用
print('5的阶乘{}'.format(digui(5)))
递归案例:模拟实现 树型结构的遍历(查找文件)
import os # 引入文件操作模块
def findFile(file_Path):
listRs=os.listdir(file_Path) # 得到该路径下所有的文件夹
for fileItem in listRs: #遍历文件夹,如果是文件夹,继续遍历,是文件,输出
full_path=os.path.join(file_Path,fileItem) #拼接完整文件路径 #获取完成的文件夹路径 (得到路径,根据路径判断是否为文件夹)
if os.path.isdir(full_path): #根据上一行得到的完整路径,判断是否是文件夹
findFile(full_path) #如果完整路径是一个文件夹 再次去递归 这个完整路径
else:
print(fileItem)
pass
pass
else: # 如果for遍历完,其中没有出现break,else中直接return
return
pass
# 调用搜索文件对象
findFile('E:课件')



