Python函数

文章目录

调用函数

Python本身就提供了很多函数直接调用,需要匹配正确的参数,如果输入的参数错误,会在错误提示中告诉你。

例如,绝对值函数,取最值函数,强制类型转换函数等。

>>> abs(-100)
100
>>> max(-1,2,3,4)
4
>>> int(12.56)
12

Python支持通过别名的方式调用函数:

>>> i=int
>>> i(12.56)
12

定义函数

格式

使用def语句定义,def后面接函数名,括号,括号中的参数以及冒号。例如,求绝对值函数:

def my_abs(x):
    if x>=0:
        return x
    else:
        return -x

注意:python中冒号的使用,不要少东西

与其他语句相同,执行到return 语句就返回,停止执行。没有return,则返回值为none。

导入函数

可以从py文件中导入函数来使用,例如

from input_output import my_abs;#此处的input_output是文件名,my_abs()是函数名
print(my_abs(-99))

占位符与类型检查

因为python中没有大括号的存在,可以使用pass作为占位符,构造空函数

def nop():#什么也不执行
	pass

因为python定义变量时没有类型,因此没有参数检查。写一个完善的函数,就需要自己做参数检查。

def my_abs(x):
    if not isinstance(x,(int, float)):
        raise TypeError("not this type")#做一个参数类型检查,如果参数类型不对,提示错误信息
    if x>=0:
        return x
    else:
        return -x

关于多个返回值

Python函数可以return 多个值,格式是在return时使用,隔开。多个返回值会以tuple的形式返回。

def mult_return(x):
    a=x+2
    return x-1,x+1,a    
print(mult_return(5))

运行结果:

(4, 6, 7)

函数的参数

位置参数

在正常情况下,python的函数参数是按,定义时的顺序传入:

例如:

def power(x,y):#计算x的y次方,依次读入x和y作为参数
    sum=1
    while y>0:
        sum*=x
        y-=1
    return sum
print(power(2,3))

运行结果:

8

默认参数

可以在传入参数时设定一个参数的值,这样可以在调用时少传入一个参数

例如:

def power3(x,y=3):# y的默认值是3
    sum=1
    for i in range(y):
        sum*=x
        # print("第%d轮\n" %i)
    return sum
print(power3(9,1))#带入两个参数,此时y的取值被覆盖
print(power3(9))#带入一个参数,y取默认值3

运行结果:

9
729

注意:在python中,函数中的参数并不是c++中的形参,而是一个变量。因此,如果讲函数参数设为可变的,那就会出问题。

例如:

def my_func(L=[]):
    L.append('zcc')
    return L
print(my_func())
print(my_func())

运行结果:

['zcc']
['zcc', 'zcc']

这是由于,作为参数的L被修改了。因此,默认参数必须指向不变对象

例如,将上面的程序进行修改,使L等于不变对象none

def  my_func2(L=None):
    if L is None:
        L=[]
        L.append('zcc')
    return L
print(my_func2())
print(my_func2())

运行结果:

['zcc']
['zcc']

这样就保证每次输出的结果都一样了

注:不变对象:tuple,str,None

可变参数

用法类似于C++的数组作为函数参数,在传入参数数量不确定时使用。

情况1:

正常定义一个参数即可,传入时传入一个tuple或者list

def my_func3(L):
    sum = 0 #注:sum是一个内置的变量名,最好不要用这个
    for i in L:
        sum += i
    return sum
L=[1,2,3,5]
print(my_func3(L)) #将L作为参数传入

但是,此时想直接传入几个变量就不行了

例如:

print(my_func3(1,2,3,4))

就会报错,因为默认一个参数。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZBlzcKfK-1631074952721)(C:\Users\26741\AppData\Roaming\Typora\typora-user-images\image-20210902103833246.png)]

因此需要先组合成list或者tuple

print(my_func3((1,2,3,4))

情况2

利用可变参数,相当于自动把传入的参数组合成tuple。免去自己组合的麻烦。这个方法有点像C语言中的取指针

def my_func4(*l1):
    sum1 = 0
    for i in l1:
        sum1 += i
    return sum1


L=(1,2,3,4)
print(my_func4(1,2,3,4))
print(my_func4(*L)) #在list或者tuple变量名前面加一个*即可

若想在可变参数中使用list或者tuple作为变量,可以直接传入。

运行结果:

10
10

关键字参数

关键词参数的变量类型必须是dict。可以是传入参数的时候作为一个key-value键值对传入,也可以就直接将一个dict变量集合传入。这种函数传递参数的方式,可以获得额外的变量值。

def my_func5(name, age, **kw):
    print('name', name, 'age', age, 'other', kw)


my_func5('Bob', 12, city='Beijing', country='China')#此处的city='Beijing',就是以键值对形式传入
info={'city': 'tianjin', 'college': 'hebut'}
my_func5('zcc', 22, **info)#想直接将dict传入需要加**

输出结果

name Bob age 12 other {'city': 'Beijing', 'country': 'China'}
name zcc age 22 other {'city': 'tianjin', 'college': 'hebut'}

注:关键字函数传入的是一个拷贝,所以在针对关键字函数作出修改之后,不会对原来造成影响。

命名关键字参数

可以传入任意数量的参数,但是只接受想要的参数。原理就是中间用一个可变参数接受多余的变量。所有的命名关键字必须以键值对的形式插入,不能没有。缺一个都会报错

情况1:使用分隔符分割

def my_func6(name, age, *, city, school):
    print('name:', name, 'age:', age, 'city', city, 'school', school)


my_func6('zcc', 22, city='baoding', school='hebut')
my_func6('zcc', 22, school='hebut', city='baoding')

这种情况下,* 后面被视为命名关键字,输入参数数量与函数定义必须数量一致。但,* 后面只要所有的命名都有,顺序可以不一致。

运行结果:

name: zcc age: 22 city baoding school hebut
name: zcc age: 22 city baoding school hebut

情况2:使用可变参数分割

def my_func7(name, age, *args, city, school):
    print('name:', name, 'age:', age, 'city', city, 'school', school)


my_func7('zcc', 22, 1, 1, city='baoding', school='hebut')

这种情况下,中间多余的参数会被可变参数吃掉。但是可变参数后面不能再有多余的参数。

虽然python中可以定义多种函数,但是调用的时候必须遵照必选参数,默认参数,可变参数,命名关键字参数和关键字参数的顺序。

递归函数

调用自身的函数,通过栈实现。

def my_func7(n):
    if(n == 1):
        return 1
    else:
        return n * my_func7(n - 1)

print(my_func7(5))

由于栈的大小有限,因此没完没了的递归。会造成栈溢出。可以使用尾递归的方式解决。即:函数本身的返回语句不包括表达式,这样就不会占用多余的栈了。

def fact(n):
    return fact1(n, 1)

def fact1(num , product):
    if(num == 1):
        return product #已经算到了最后一步
    else:
        return fact1(num-1, product * num) #乘以当前的数


print(fact(5))

不用让栈等着参数被计算,而是直接计算完。类似于循环。

上一篇:DOM之select联动效果


下一篇:go学习-struct