函数
面向对象编程: 类----class
面向过程编程:过程---def
函数式编程:函数---def
def test(x):
'''描述'''
x +=1
return x
#def是定义函数的关键字
#test是函数名称
#(x)是参数
#x+=1是 函数体,是一段逻辑代码
#return 定义返回值,返回给test函数 ,并结束函数
1.
def func1():
'''test'''
print ('in the func1')
return 0
#函数式编程
def func2():
'''test2'''
print ('in the func2')
#定义面向过程的函数,没有return; 过程就是没有返回值的函数
x = func1()
y = func2()
print ('from func1 return is %s' %x)
print ('from func2 return is %s' %y)
虽然过程函数没有return,但是python会隐式的给返回一个None,所以两者差别并不大
2.
def logger():
with open('test.txt','a') as f:
f.write('end action\n')
def test1():
print('in the test1')
logger()
def test2():
print('in the test2')
logger()
def test3():
print('in the test3')
logger()
test1() #执行函数
test2()
test3()
#可以看到三个函数都调用了logger这个函数,否则的话,我们需要在每三个函数中都要写
#with open这些代码; 调用了logger函数的话,就免去写重复的代码了。
我们要在三个函数每次写入的时候都加入时间戳
import time
def logger():
time_format = '%Y-%m-%d %X' #定义格式为年、月、日、小时分钟秒
time_current = time.strftime(time_format) #显示时间,以time_format定义的格式来显示
with open('test.txt','a') as f:
f.write('%s end action\n' %time_current)
#修改logger函数,这样test的三个函数就全都被修改了。
#时间格式%后面的字母根据大小写的不同,显示的格式也不同。
执行后看到文档内容
定义函数的好处: 代码重用 保持一致性(修改代码不会因为认为的原因导致相同的代码写错后不一致) 可扩展性
3.
return除了会返回值给函数,还终止函数的运行,所以后面的print没有打印。
s = test()
print (s)
return 将0返回给了test函数,赋值变量后,这个变量就等于这个return的值。
return几乎可以返回任何类型
为什么要用return,return的作用是什么: 在编程使用函数时,可能代码会很多,然后根据不同的结return不同的值,根据不同的值可以用作下面代码的判断,然后做不同的动作; 比如根据True或False,下面的代码执行不同的操作。
定义三个函数,一个没有return,一个return单个元素数字,一个return多个元素
没有return默认返回None
return单个元素,会正常返回定义的值
return多个元素,会通过元组返回(相当于一个打包,然后一起返回)
4.
定义带参数的函数
调用函数时,如果不赋值给参数就会报错
赋值给参数,位置要对应.
1赋值给了x
2赋值给了y
x与y叫做形参:需要引用、被赋值的参数
1与2叫做实参:实际的参数
1与2是真是存在的,会在内存中占用空间;x与y是形式上的参数,如果x与y没有引用任何值,则不会占用内存空间。
默认的情况下,赋值参数需要位置一 一对应,否则的话就需要指定参数的赋值
位置参数和关键词参数是可以混写的,默认参数需要位置对应,1赋值给了x,2赋值给了y
这样赋值是会报错的,第一个赋值是y=1(使用的是关键词参数赋值),第二个我们使用的是位置参数赋值,但是第二个参数根据位置应该对应的是y,课时y在前面已经被占用了,所以会报错。
可以看到关键参数在位置后面写就没有报错;
5.
在创建函数时,可以给参数赋值默认的值
在给参数赋值时,如果不从新赋值,那么参数就会使用创建函数时给赋予的默认值
可以通过位置和关键词来修改默认参数值
把参数从新赋值就不会使用默认参数值了,会使用新的赋值来覆盖默认的参数值
默认参数的用途:比如安装软件的默认路径,或者一些默认勾选的选项; 比如设置某个程序的默认端口等等。
6.参数组
当定义一个函数的参数时,实参不能少于或多于形参,否则执行就会报错; 有多少个实参,定义函数时就得定义多少个形参,但是如果参数需要一万个,则不可能去写一万个参数。
所以这里我们可以使用参数组;当需要的参数数量过多或者实参所需求的数量不明确时,就可以使用参数组;
定义参数组的关键符号是‘*’,后面定义一个组名即可
可以看到定义多少个参数都可以,打印时以元组形式打印出来。
‘*’ 用来接收N个位置参数,转换成元组;不能接收关键字参数。。
传参数值的时候,也可以使用*,比如(*[1,2,3,4,5]),只不过打印出来的时候会转换成元组
使用两个*,表示可以传入字典参数; 把N个关键字参数,转换成字典的方式。
‘’用来接收N个关键字参数,转换成字典。
test(**{'name':'zhangsan','age':20})
传入参数也可以使用两个**,只不过字典的写法稍有差别
打印字典key对应的value
def test3(name,**kwargs):
print (name)
print (kwargs)
test3(123)
位置参数和参数组一起使用;
这里没有定义参数组的值,所以打印出来为空的字典
def test3(name,**kwargs):
print (name)
print (kwargs)
test3('lisi',age=20,sex='M')
位置参数和参数组的值,被分开打印了
def test4 (name,age=18,**kwargs): #在写普通参数和参数组时,要把参数组写在后面
print (name)
print (age)
print (kwargs)
test4('lisi',sex='M',hobby='car')
使用两个位置参数和一个参数组;第二个位置参数被打印的是默认值
test4('lisi',sex='M',hobby='car',age=20)
age位置参数不使用默认值,根据关键字参数的方式对其修改
test4('lisi',22,sex='M',hobby='car')
age根据位置参数的方式对其修改
*args 接收N个位置参数;**kwargs接收N个关键字参数; 在赋值个参数时,后面并没有符合位置参数的值,所以打印位置参数会显示一个空的元组。
test5 ('lisi',33,44,55,66,sex='M',hobby='car')
这样4种参数就都可以体现出来了
函数嵌套函数;
可以看到此处的代码与上面的一样,只是logger这个函数在调用函数的下面,执行时就会报错,所以在调用函数时,一定要在相关函数的下面去掉用,否则是找不到相关内容的。