MyPython-->进阶篇-->函数
函数是带名字的代码块,用于完成具体工作
下面是打印问候的一个简短函数
def hello():
''' 显示hello''' print('hello')
关键字def告诉python,你要定义一个函数,这是 函数定义,像python指出了函数名,()内时为完成函数功能需要的信息,这里不需要。括号是必不可少的。最后冒号结尾
紧跟在函数:后面的所有缩进行构成了函数体。'''''''内的被称为文档字符串的注释,描述了函数是做什么的,由三个引号括起,python使用它们来生成有关程序中函数的文档
调用它
hello()
可以传一个参数
def hello(name): '''打印hello''' print('hello %s'%name) hello('cc')
以上代码 name是形参,而'cc'是实参。实参被储存在形参中
位置参数
def cat (name,age): print('%s %s'%(name,age)) cat('coco',2)
位置参数,位置很重要不要弄反了
直接传递给函数 名称-值对,这样顺序错了也没事
cat(age=3,name='cool')
默认值参数
def dog(name,color='black'): print(name,color) dog('gk') dog('gg',color='red')
注意要给默认参数提供值,必须加上color= 默认参数必须指向不可变对象
可变参数
def cal (*numbers)
顾名思义,就是可以传入任意数量的参数。
要定义出这个函数我们必须确定输入的参数,由于参数个数不确定,我们首先想到的是把他们放到一个list或者tuple传进来
def he(number): '''返回传入列表的和''' sum = 0 for x in number: sum+=x return sum print(he([1,2,3,4]))
但是调用的时候,需要先组装出一个list或者tuple很麻烦
我们可以这样简化
def cal(*number): sum = 0 for x in number: sum+=x return print(sum) cal(1,2,3,4,5)
定义一个可变参数,仅仅是在参数前面加了一个*号。在函数内部,参数numbers接收到的是一个tuple,因此函数代码完全不用改变,可以传入任意个参数包括0个参数
如果已有一个列表或者元祖怎么办,python支持直接加*就可以使用
关键字参数
def cal(name,age,**kw)
可变参数允许传入任意个参数,自动组装为元祖。而关键字参数允许你传入任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict
1 def cal2(name,age,**kw): 2 print(name,age,kw) 3 cal2('cc','23') 4 cal2('cc','23',city='beijing')#cc 23 {'city': 'beijing'}
注意最后一行,添加方式。
同样已有的字典我们可以加** 使用
命名关键字参数
对于关键字参数,函数的调用者可以传入任意不受限制的关键字参数。至于到底传入了什么,就需要在函数内部通过kw检查
要限制关键字参数的名字,就可以用命名关键字参数,比如只接受city和job作为关键字参数
和关键字参数**kw
不同,命名关键字参数需要一个特殊分隔符*
,*
后面的参数被视为命名关键字参数。
def person(name,age,*,job,city): print(name,age,job,city) person('cc',23,job='qa',city='bj')
命名关键字参数必须传入参数名,如果没有会报错,可以增加默认值,简化调用
def person( name , age , * , job = 'qa' , city): print(name , age , job , city ) person('cc',23,city='bj')
调用的时候如果,不填job会使用默认的值,也不会报错
对于任意函数,我们都可以通过类似func(*args,**kw)调用它
小结
Python的函数具有非常灵活的参数形态,既可以实现简单的调用,又可以传入非常复杂的参数。
默认参数一定要用不可变对象,如果是可变对象,程序运行时会有逻辑错误!
要注意定义可变参数和关键字参数的语法:
*args
是可变参数,args接收的是一个tuple;
**kw
是关键字参数,kw接收的是一个dict。
以及调用函数时如何传入可变参数和关键字参数的语法:
可变参数既可以直接传入:func(1, 2, 3)
,又可以先组装list或tuple,再通过*args
传入:func(*(1, 2, 3))
;
关键字参数既可以直接传入:func(a=1, b=2)
,又可以先组装dict,再通过**kw
传入:func(**{'a': 1, 'b': 2})
。
使用*args
和**kw
是Python的习惯写法,当然也可以用其他参数名,但最好使用习惯用法。
命名的关键字参数是为了限制调用者可以传入的参数名,同时可以提供默认值。
定义命名的关键字参数在没有可变参数的情况下不要忘了写分隔符*
,否则定义的将是位置参数。
之前提到过的转移列表元素可以写入方法直接调用
1 def move(list1,list2): 2 while list1: 3 l = list1.pop() 4 print('%s move to %s'%(l,list2)) 5 list2.append(l) 6 for x in list2: 7 print(x) 8 9 l1 = [1,2,3,4,5] 10 l2 = [] 11 move(l1,l2)
这里会把list1的列表删干净,我们可以在传入的时候复制一下列表list1[:] 这样就不会把原列表删除,或者修改函数
1 def move(list1,list2): 2 list3 = list1[:] 3 while list3: 4 l = list3.pop() 5 print('%s move to %s'%(l,list2)) 6 list2.append(l) 7 for x in list2: 8 print(x) 9 10 l1 = [1,2,3,4,5] 11 l2 = [] 12 move(l1,l2)
第二行我们直接复制了传入的列表,这样也不会修改 原来的列表
将函数储存在模块中
导入整个模块,导入整个模块会把全部代码复制过来虽然看不见,但是是有的。
要让函数是可以导入的,先创建模块,模块是扩展名叫.py的文件,包含要导入到程序中的代码
import etmake from etmake import et_make import day9.etmake
导入etmake.py这个模块,可以使用其中的方法
导入etmake.py这个模块的et_make方法
导入day9目录下etmake.py这个模块
如果要导入的函数名跟程序有冲突可以取个别名 as 后跟别名
from etmake import et_make as et_m
同样可以对模块取别名
import etmake as etm
使用*号可以导入模块的所有函数
from etmake import *
小心使用全部导入,如果模块内有跟你程序重名的会带来意想不到的结果
函数编写指南
描述性的函数名使用小写字母和下划线,文档字符串格式。默认值赋值是=号两边不要加空格