函数定义和调用
函数
函数就是一些列python语句的组合,可以在程序中一次或多次,一般是完成具体的独立功能。
使用函数是为了复用最大化及最小代码冗余,整体代码结构清晰,问题局部化。
函数定义:
def function():
代码块
函数调用:函数名+()即可调用,本质上就是执行函数定义的代码块,在调用之前,必须先定义。
def my_func():
print("my name is Mike")
print("I'm 12 years old")
my_func()
#运行结果
my name is Mike
I'm 12 years old
参数
参数:在定义函数时,在括号定义n个参数(变量),并在调用时给其赋值。
def my_func(name=,age):
print("my name is %s,"%name,end="")
print("I'm 12 years %d"%age)
my_func()
my_func("Bob",16)
#运行结果
my name is Bob,I'm 12 years 16
参数的分类:必填参数、默认参数、可选参数、关键字参数。
参数:其实就是函数为了实现某项特定的功能,进而为了得到实现功能所需要的数据。
必填参数
在调用时,必须填写参数,且填写完整(每个参数都要填),否则会报错。
def sum(a,b): #在这里a和b形式参数(形参),只是意义上的参数,在定义时不占用内存地址
sum=a+b
print(sum)
sum(1,2) #这里的1和2是实际参数(实参),会占用内存地址
#运行结果
3
默认参数
在调用函数时,如果未赋值,就会将默认值赋值给参数,如果有两个以上有默认值的参数,如果在调用时只填写一个参数值,则该值只能赋值给第一个参数。
def sum(a=2,b=3):
sum=a+b
print(sum)
sum(1,2)
sum(3)
sum()
#运行结果
3
6
5
可变参数
可传入任意个参数,通过输出发现,参数实际以元组的形式存储。
def flex(*args):
print(args)
flex((1,2,3,4,5))
flex(1,2,3,4,5)
flex([1,2,3])
#运行结果
((1, 2, 3, 4, 5),)
(1, 2, 3, 4, 5)
([1, 2, 3],)
def flex(*args):
print(args)
sum=0
for items in args:
sum=sum+items
print(sum)
flex(1,2)
flex(1,2,3,4,5)
#运行结果
(1, 2)
3
(1, 2, 3, 4, 5)
15
关键字参数
用两个星号定义,在函数体内,参数关键字是一个字典类型的,key是一个字符串,关键字参数可以不赋值。
def keyfunc(**kwargs):
print(kwargs)
#keyfunc(1,2,3) 不可以运行
dict={"name":"Mike","age":12}
keyfunc(**dict)
keyfunc(name="Peter",age=16)
keyfunc()
#运行结果
{'name': 'Mike', 'age': 12}
{'name': 'Peter', 'age': 16}
{}
参数组合使用
注意:可选参数必须放在关键字参数之前。
def comfunc(*args,**kwargs):
print(args)
print(kwargs)
comfunc(1,2,3,4)
comfunc(1,2,3,4,name="mike")
comfunc(age=15)
#运行结果
(1, 2, 3, 4)
{}
(1, 2, 3, 4)
{'name': 'mike'}
()
{'age': 15}
函数返回值
在函数执行完以后要返回一个对象,如果在函数内部有return,就可以返回实际值,否则返回为空。返回值可以返回任意类型,取决于return后面的类型。
在一个函数内可以出现多个return,但是肯定只能返回一个return,如果在一个函数体内执行了return,函数就执行完成退出了,return后面的代码语句将不再执行。
def sum(a,b):
sum=a+b
return sum
result=sum(10,20)
print(result)
#运行结果
30
如果不加return
def sum(a,b):
sum=a+b
result=sum(10,20)
print(result)
#运行结果
None #返回为空
返回结果可以是任意数据类型,比如列表
def cal(a=10):
li=[]
result=0
i=1
while i<=a:
result+=i
i+=1
li.append(result)
return li
b=cal(5)
print(b)
#运行结果
[1, 3, 6, 10, 15]
函数嵌套调用
定义函数时,可在代码块中调用其他已经定义的函数。
def func1():
print("this is a function")
def func2():
func1()
print("this is another function")
func2()
#运行结果
this is a function
this is another function
应用
写一个函数,找出传入的若干个列表或元组的偶数位对应的元素,并返回新列表:
def func_sum(*args):
a=len(args)
li=[]
for n in range(0,a):
b=len(args[n])
for m in range(0,b):
if m%2==0:
li.append(args[n][m])
return li
new_li=func_sum([1,2,3,4,5,],(1,2,3,4,5))
print(new_li)
#运行结果
[1, 3, 5, 1, 3, 5]
写一个函数,检查传入字典的每一个value的长度,如果大于2,那么保留前两个长度的内容,并将截取的字符串修改到原来的字典中,字典中中的value只能是字符串或者列表。
def func_sum(kwargs):
result={}
for key,value in kwargs.items():
if len(value)>2:
result[key]=value[:2] #向字典添加数据
pass
else:
result[key]=value
pass
pass
return result
dict_obj={"name":"Mike","age":"20","pro":"art","hobby":"computer games"}
print(func_sum(dict_obj))
#运行结果
{'name': 'Mi', 'age': '20', 'pro': 'ar', 'hobby': 'co'}
局部变量和全局变量
局部变量就是在函数内部定义的变量,作用域仅仅局限在函数的内部,所以不同函数可以定义名字相同的变量,不会相互影响。
作为函数内临时保存数据的存储容器;全局变量作用在整个代码中,包括定义的函数中。
局部变量相当于地头蛇,只在自己函数体内生效,而全局变量在全部局生效,但当局部和全局重复定义时,会优先执行局部变量,即强龙不压地头蛇。
name="Mike"
def func():
user_name="Alice"
print(name,user_name)
pass
func()
#运行结果
Mike Alice
如果在函数体内部对全局变量进行,修改需要使用global函数。
name="Mike"
def func():
user_name="Alice"
global name
name = "Bob"
print(name,user_name)
pass
func()
#运行结果
Bob Alice
函数参数引用传值
在Python当中,万物皆对象,在函数调用的时候,实参传递的就是对象的引用;
了解原理后,就可以知道在函数内部的处理是否会影响外部数据的变化。
a=1 #不可变类型
def func(x):
print("x的内存地址是{}".format(id(x)))
x=2
print("x的内存地址是{}".format(id(x)))
print(x)
pass
print("a的内存地址是{}".format(id(a)))
func(a)
print(a)
#运行结果
a的内存地址是2199487736112
x的内存地址是2199487736112
x的内存地址是2199487736144
2
1
li=[] #可变类型
def func(x):
print("x的内存地址是{}".format(id(x)))
print("x的内存地址是{}".format(id(x)))
li.append([1,2,3])
print("函数内部的li={}".format(li))
pass
print("li的内存地址是{}".format(id(li)))
func(li)
print("函数外部的li={}".format(li))
#运行结果
li的内存地址是2458644007872
x的内存地址是2458644007872
x的内存地址是2458644007872
函数内部的li=[[1, 2, 3]]
函数外部的li=[[1, 2, 3]]
匿名函数
使用lambda关键字创建函数;没有名字;匿名函数冒号后的表达式只能有一个(是表达式,而不是语句);匿名函数自带return,而这个return的结果就是表达式计算后的结果。
lambda只能是单个表达式,不是一个代码块,labmda的设计就是为了满足简单函数的场景,仅仅能封装有限的逻辑,复杂逻辑无法实现。
lambda 参数1、参数2…参数n:表达式
result=lambda x,y,z:x+y+z
print(result(1,2,3))
#运行结果
6
也可以用于替换双分支if语句:
a,b=2,1
print('suscess' if a>b else 'false')
#运行结果
suscess
直接在匿名函数后面传参:
result=(lambda x,y:x if x>y else y)(16,12)
print(result)
#运行结果
16
递归函数
递归函数即自己调用自己,且必须有一个明确的结束条件;递归函数逻辑简单、定义简单,但也溶质导致栈溢出,内存资源紧张,甚至内存泄漏。
def func(n):
if n==1:
return 1
else:
return n*func(n-1)
print("5的阶乘是{}".format(func(5)))
#运行结果
5的阶乘是120
案例:树形结构的遍历。
import os #引入文件操作模块
def find_file(file_path):
list=os.listdir(file_path) #得到该路径下所有文件夹
for file in list:
full_path=os.path.join(file_path,file) #获取完整路径
if os.path.isdir(full_path): #判断是否为文件夹
find_file(full_path) #如果是文件夹,再次去递归
else:
print(file_path)
pass
pass
else:
return
pass
find_file('D:\INSTALL\知犀\知犀思维导图')
#运行结果
chrome_100_percent.pak
chrome_200_percent.pak
d3dcompiler_47.dll
ffmpeg.dll
...