python 函数

函数

是可以重复使用进行用来实现单一,或相关联功能的代码块。

一、无入参的函数

#函数
def func1():
    '''函数的功能描述'''
    print("in the func1")
    return 0

#过程
def func2():
    '''打印in the func2'''
    print("in the func2")

x = func1()
y = func2()

print(x)
print(y)

上述代码中,func1中有return 0;func2没有返回;在后续的赋值操作时,可以看到x=0;y为None

使用函数实现记录日志的功能

import time
def log():
    '''通过获取当前时间打日志追加到同级目录的log.txt文件中'''
    time_format = '%Y-%m-%d %X'
    time_curent = time.strftime(time_format)
    with open('log.txt','a+',encoding='utf-8') as f:
        f.write('%s this is log....
' %time_curent)

print('in the test1')
log()

其中用到了time模块中的strftime方法,可以参照https://www.runoob.com/python/att-time-strftime.html中的进行参考;

函数的优点:可重复使用的,扩展性更高,使代码变得简单

函数的返回值

在第一段函数中可以发现有return

return返回值可以是多中多样的,可以不写,这样返回就是None

返回一个数字

返回一个列表

返回一个字典,都可以进行返回

如果返回多个数据

def test4():
    print('in the test4')
    return 0,1,[0,'fdj'],{'key':'vlalue'}

那么返回的结果是以元组的形式进行返回:(0,1,[0,'fdj'],{'key':'vlalue'})

那为什么我们要有返回值

第一点:首先return是对函数的一个终结,表明到这里函数执行结束了;

def test3():
    print('in the test4')
    return 0,1,[0,'fdj'],{'key':'vlalue'}
    print('in the test3')

比如上方的这段代码,return之后,后面 print('in the test3')就不会再执行了

第二点:函数的返回值,可以对后续的操作进行影响,比如我们一个返回的是1我们后续可能走这段逻辑;如果返回时0可能走另外一段逻辑

二、包含参数的函数

在对函数进行定义的时候,可以根据函数的情况,进行传参

1位置参数

def test1(x,y,z):
    print(x)
    print(y)
    print(z)
    return 0

test1(3,2,1)

上段代码中我们给test1()传了3个参数,这种参数属于位置参数,和函数定义的参数位置一一对应

2关键字参数

def test1(x,y,z):
    print(x)
    print(y)
    print(z)
    return 0

test1(3,2,z=1)

上面的代码呢,我们按照位置传了两个参数,还指定了z=1;其中z=1这种就叫关键字参数

同样也可以全部都进行指定

比如

test1(y=3,x=2,z=1)

如果是这样:

test1(3,x=2,1)运行的时候回提示报错,原因是python中指定参数要放在位置参数的后面;

3默认参数

默认参数就是在定义函数传参的时候可以进行参数传默认值,例如

def test1(x,y,z=4):
    print(x)
    print(y)
    print(z)
    return 0

test1(3,2)

test1函数有3个参数,但是我们调用的时候只传了两个,因为有默认参数,我们可以不传;当然也可以传,这样对应得参数以最后一次传参的值为准

比如我们在使用数据库的端口号的时候就可以使用默认传参,如sql:1433 oracle:3366

4参数组

上面说的参数都是固定的,我们在现实的应用中都会出现,我们没有想好的情况,是否确定参数的个数,我们想要参数不是固定的,这个时候,就引入了参数组的概念

def test2(*args):
    print("so many parameter")
    return 0

test2(1,2,3,5)

上面的代码中*args就是定义了一个参数组,我们去调用的时候就可以函数的应用随机的去传相应的函数,便于函数后期的扩展

上面再调用test2的时候还可以这样传参test2(*[1,2,3,5])和test2(1,2,3,5)是一样的额效果,这种是将参数转为元组;

如果我想要字典的形式,可以使用如下方式

def test3(**kwargs):
    print(kwargs)
    return 1

test3(name = 'axiang',age = '28')

输出的结果是一个字典:

{name:'axiang',age:'28'}

同样还可以使用test(**{name:'axiang',age:'28'})这种方式调用

如果我想获取name对于的value的时候可以

kwargs['name']

上述的内容*args是把N个位置参数转化为元组的方式;**kwargs是把N个关键字参数转换成字典的方式

局部变量和全局变量

def change_name(name):
    print("before change ",name)
    name = 'axiang'
    print('after change ',name)

name = 'lxiang'
change_name(name)
print(name)

运行结果

before change  lxiang
after change  axiang
lxiang

可以看到change_name函数中定义的name称之为局部变量,在顶层的定义的为全局变量,差别就是作用域不同

局部变量的作用域在函数体内;全局变量的作用域是全局的

如果想在函数中定义全局变量,可以使用global进行定义,表示为全局变量

递归函数

在函数内部自己调用自己

1.必须要有个结束条件

2.每次进入更深一层递归时,问题规模相比于上次递归都应该减少

3.递归效率不高,递归的层次过多会导致栈溢出

def  calc(n):
    print(n)
    if int(n) > 0:
        return calc(int(n/2))

calc(10)

高阶函数

定义的函数里面调用函数,称为高阶函数

def add(a,b,f):
    return f(a)+f(b)

res = add(3,-6,abs)#abs(-6) = 6;绝对值函数
print(res)

运行的结果是 9