python(五)之函数基础-->参数,全局变量,局部变量
一,什么是函数?
用来实现某一个功能的方法
二,函数的分类?
内置函数:针对一些简单的功能,python已经给我们定义好了的函数,即内置函数,对于内置函数,我们拿来用就行,如:sum(),len(),count()
自定义函数:因为内置函数不可能实现我们想要的所有的功能,所以就需要我们自己编写代码实现我们所期望的功能,以便以后拿来继续使用,这种叫自定义函数
三,如何自定义函数?
def 函数名(args1,args2,args3......):
'''
注释
'''
函数体
return 返回值
ps:函数一定要先定义,然后才能被调用或者被引用
四,函数在定义阶段都做了什么呢?
只检查语法,不执行代码,也就是说在定义的时候,函数的语法就能检查出来,而逻辑性的错误,只有函数执行的时候才能检查出来
五,函数的类别
a,面向对象:类-->class
b,面向过程:过程--->def :函数无返回值
c,函数式编程:函数---> def
六,为什么要使用函数?
代码重用,可扩展,保持统一
七,函数的参数
A,实参和形参:形参其实就是变量名,实参其实就是变量的值,把值传给变量名,叫做传参
B,具体的应用场景
a,位置参数,按照从左到右的顺序定义参数
位置形参:必选参数
位置实参:按照位置给形参传值,要一一对应
def test(x,y): #x和y就是形式参数
print(x)
print(y)
test(1,2) #1和2就是实际参数,传参数的时候是把1传给x,2传给y,与形式参数一一对应
b,关键字参数:按照key=value的形式定义的实参
无需按照位置参数传参
关键字参数必须在位置参数的后面
同一个参数不能重复传值
关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict
#_*_coding:utf-8_*_
def person(name,age,**kw): #**表示关键字参数,即接收参数的时候,必须要指定参数的名和值
print('name:', name, 'age:', age, 'other:', kw)
person('Michael', 30) #默认传位置参数的值,打印结果为:('name:', 'Michael', 'age:', 30, 'other:', {})
person('Bob', 35, city='Beijing') #传一个关键字参数,结果为:name: Bob age: 35 other: {'city': 'Beijing'}
person('Adam', 45, gender='M', job='Engineer') #传两个关键字参数,结果为:name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'}
#以上看出来**后面的变量其实接收的是一个字典
c,默认参数,在形式参数定义的时候就赋值
可以传值,也可以不传值。如果传值就用传的值,否则就用默认值
注意事项:
1. 只在定义时赋值一次
2. 默认参数的定义应该在位置形参右面
3. 默认参数通常应该定义成不可变类型def power(x, n=2):
s = 1
while n > 0:
n = n - 1
s = s * x
return s
d,可变参数
可变参数指的是实参个数不固定,二形参要全部的接收实际参数。
实际参数有位置参数和关键字参数这两种定义的参数,针对这两种可变长参数,形式参数有比较合理的接收参数来接收他们,分别是:*args(可变参数), **kwargs(可命名参数)
def test(x,y,*args): #位置可变参数,可以传0个或者任意的参数值,args以tuple形式接收参数
print(x,y)
print(args)
#test(1,2,3,4,5) #打印结果:(1, 2)、(3, 4, 5)
test(1,2,[3,4,5]) #打印结果:(1, 2)、([3, 4, 5],) 此时把[3,4,5]作为一个整体去传递
test(1,2,*[3,4,5]) #打印结果:(1, 2)、(3, 4, 5) 此时把[3,4,5]当成了单个参数去传递
def test001(x,y,z):
print(x,y,z)
test001(*[1,2,3])#打印结果:(1, 2, 3) ,此时把[1,2,3]分开传递
--------------**kwargs--------------------
关键字参数 def test(x,y,**kwargs):
print(x,y)
print(kwargs)
test(1,y=2,a=1,b=3) #输出结果:(1, 2)、{'a': 1, 'b': 3}
test(1,2,**{'a':1,'b':2}) #输出结果:(1, 2)、{'a': 1, 'b': 2}
def test01(x,y,z):
print(x,y,z)
test01(**{'x':1,'z':2,'y':3}) #这里的key一定要和形式参数中的参对应
e,命名关键字参数,*后面定义的参数,必须要传值(默认值除外)
#如果要限制关键字参数的名字,就可以用命名关键字参数,例如,只接收city和job作为关键字参数。这种方式定义的函数如下:
def person(name, age, *, city, job):
print(name, age, city, job)
person('Jack', 24, city='Beijing', job='Engineer') #Jack 24 Beijing Engineer
#如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符*了:
def person(name, age, *args, city, job):
print(name, age, args, city, job)
六,高阶函数
变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数称之为高阶函数。
七,变量的作用域
1,局部变量
是指在函数内部定义并使用的变量,它只在函数内部有效。即函数内部的名字只在函数运行时才会创建,在函数运行之前或者运行完毕之后,所有的名字就都不存在了。所以,如果在函数外部使用函数内部定义的变量,就会出现抛出NameError异常。
2,全局变量
(1)如果一个变量,在函数外定义,那么不仅在函数外可以访问到,在函数内也可以访问到。在函数体以外定义的变量是全局变量。
注:当局部变量与全局变量重名时,对函数体的变量进行赋值后,不影响函数体外的变量。
(2)在函数体内定义,并且使用global关键字修饰后,该变量也就变为全局变量。在函数体外也可以访问到该变量,并且在函数体内还可以对其进行修改
从上面的结果中可以看出,在函数内部定义的变量即使与全局变量重名,也不影响全局变量的值。那么想要在函数体内部改变全局变量的值,需要在定义局部变量时,使用global关键字修饰。如下:
注:尽管python允许全局变量和局部变量重名,但是在实际开发时,不建议这么做,因为这样容易让代码混乱,很难分清哪些是全局变量,哪些是局部变量。
3,递归