初识函数——函数的定义、返回值和参数

函数的定义

在Python中,用关键字def关键字来定义函数,如下:

def greet_hello():
    print("hello!")
    
greet_hello()

关键字def后面是函数名, 它其实就是一个标识符。后面的括号必须有,里面可以有参数。函数定义,只是声明了一个函数,它不会被执行,需要调用,函数的调用很简单,直接函数名加括号就调用了。定义需要在调用前,也就是说调用时,已经被定义过了,否则抛NameError异常

函数的作用

  1. 功能封装,便于后面复用。
  2. 减少冗余代码。
  3. 代码更易读。

函数的返回值

函数的返回值一般有四种情况:

  1. 没有返回值,默认会返回None。
  2. 直接一个return,默认返回None。
  3. 返回一个值。
  4. 返回多个值,返回多个值其实也相当于返回一个,返回的多个值用元组接收。可以返回任意数据类型的值。

返回一个值

def mylen(s1):
    """计算s1的长度"""
    length = 0
    for i in s1:
        length = length+1
    return length

#函数调用
str_len = mylen("abc")
print('str_len : %s'%str_len)

结果为3

返回多个值

def ret_demo1():
    '''返回多个值''' 
    return 1,2,3,4


def ret_demo2():
    '''返回多个任意类型的值'''
    return 1,['a','b'],3,4

ret1 = ret_demo1()
print(ret1)
ret2 = ret_demo2()
print(ret2)

结果为:
(1, 2, 3, 4)
(1, ['a', 'b'], 3, 4)

应当注意的是,函数执行时,一旦遇到return,就会结束整个函数

def ret_demo():
    print(111)
    return
    print(222)

ret = ret_demo()
print(ret)

结果为1111
     None

可以看到,后面return后面的语句没有执行了。

函数的参数

参数分为形参和实参,函数定义时为形参,函数调用时为实参。参数调用时传入的参数要和定义的个数相匹配(可变参数例外)

传递多个参数

def mymax(x,y):
    the_max = x if x > y else y
    return the_max

ma = mymax(10,20)
print(ma)
结果:20

位置实参

位置参数也就是按照参数定义顺序传入实参,传入的实参个数需要和定义的形参个数匹配。比如def f(x, y, z) 调用使用 f(1, 3, 5) ,此时是一一对应的。

关键字实参

def f(x, y, z) 调用使用 f(x=1, y=3, z=5) ,使用形参的名字来出入实参的方式,如果使用了形参名字,那么传参顺序就可和定义顺序不同。

位置实参和关键字实参混合

应当注意,位置参数必须在关键字参数的前面,同时,对于一个形参只能赋值一次。

def mymax(x,y):
    #此时x = 10,y = 20
    print(x,y)
    the_max = x if x > y else y
    return the_max

ma = mymax(10,y = 20)
print(ma)

默认值参数

默认值参数也就是在定义的时候,给参数一个默认值,也叫缺省值。参数的默认值可以在未传入足够的实参的时候,对没有给定的参数赋值为默认值。默认值参数必须要在后面,不然会报错。

 

给他们传参的时候跟上面的关键字和默认值传参规则一样。

应该注意的是,如果默认值传参的是一个可变数据类型。后期的结果会保留前面的结果。

def defult_param(a,l = []):
    l.append(a)
    print(l)

defult_param('alex')
defult_param('egon')

结果为:
['alex']
['alex', 'egon']

可变参数

可变参数分为位置参数的可变参数和关键字参数的可变参数。

位置参数的可变参数*

按位置传值多余的参数都由args统一接收,保存成一个元组的形式。

def mysum(*args):
print(args) the_sum
= 0 for i in args: the_sum+=i return the_sum the_sum = mysum(1,2,3,4) print(the_sum)

(1, 2, 3, 4)
10

 

关键字参数的可变参数**

形参前使用**符号,表示可以接收多个关键字参数,收集的实参名称和值组成一个字典 。

def stu_info(**kwargs):
    print(kwargs)
    print(kwargs['name'],kwargs['sex'])

stu_info(name = 'alex',sex = 'male')

结果为:

{'name': 'alex', 'sex': 'male'}
alex male
位置可变参数和关键字可变参数的混合

混合使用参数的时候,可变参数要放到参数列表的最后,普通参数需要放到参数列表前面,位置可变参数需要在关键字可变参数之前。

def fn(x, y, *args, **kwargs):
    print(x)
    print(y)
    print(args)
    print(kwargs)

fn(3,5,7,9,10,a=1,b='python')

3
5
(7, 9, 10)
{'a': 1, 'b': 'python'}

fn(3,5)

3
5
()
{}

fn(3,5,7)

3
5
(7,)
{}

fn(3,5,a=1,b='python')

3
5
()
{'a': 1, 'b': 'python'}

fn(7,9,y=5,x=3,a=1,b='python')

TypeError: fn() got multiple values for argument 'y'

 

当位置可变参数放在了最前面,后面的普通参数变成了keyword-only参数。
def fn(*args, x, y, **kwargs):
    print(x)
    print(y)
    print(args)
    print(kwargs)

fn(3,5)

TypeError: fn() missing 2 required keyword-only arguments: 'x' and 'y'

fn(3,5,7)

TypeError: fn() missing 2 required keyword-only arguments: 'x' and 'y'

fn(3,5,a=1,b='python')

TypeError: fn() missing 2 required keyword-only arguments: 'x' and 'y'

fn(7,9,y=5,x=3,a=1,b='python')

3
5
(7, 9)
{'a': 1, 'b': 'python'}

 

keyword-only参数

如果在一个星号参数后,或者一个位置可变参数后,出现的普通参数,实际上已经不是普通的参数了,而是keyword-only参数。就像上面的例子一样。而如果是关键字可变参数在前面,像def daf(**kwargs, x)则会直接报语法错误,可以理解为kwargs会截获所有的关键字参数,就算你写了x=5,x也永远得不到这个值,所以语法
错误。
def fn(*, x,y):
*号之后,普通形参都变成了必须给出的keyword-only 参数
print(x,y) fn(x=5,y=6)

 

可变参数和参数默认值

def fn(*args,x = 5):
    print(x)
    print(args)

fn()#等价于fn(x=5)

5
()

fn(5)

5
(5,)

fn(x=6)

6
()

fn(1,2,3,x=6)

6
(1, 2, 3)
def fn(y,*args,x=5):
    print("x={},y={}".format(x,y))
    print(args)


fn()
TypeError: fn() missing 1 required positional argument: 'y'

fn(5)

x=5,y=5
()

fn(x=6)

TypeError: fn() missing 1 required positional argument: 'y'

fn(1,2,3,x=10)

SyntaxError: positional argument follows keyword argument

fn(1,2,y=3,x=10)

TypeError: fn() got multiple values for argument 'y'

 

可变参数和关键字可变参数

def fn(x=5,**kwargs):
    print("x={}".format(x))
    print(kwargs)
fn()

x=5
{}

fn(5)

x=5
{}

fn(x=6)

x=6
{}

fn(y=3,x=5)

x=5
{'y': 3}

fn(3,y=10)

x=3
{'y': 10}

 

由此可见,参数列表参数一般顺序是,普通参数、缺省参数、可变位置参数、keyword-only参数(可带缺省值)、可变关键字参数 。

参数解构

给函数提供实参的时候,可以在集合类型前使用*或者**,把集合类型的结构解开,提取出所有元素作为函数的实参 。非字典类型使用*解构成位置参数 ,字典类型使用**解构成关键字参数 。提取出来的元素数目要和参数的要求匹配,也要和参数的类型匹配。

def add(x,y):
    return x+y
add(4,5)

9

add((4,5))

TypeError: add() missing 1 required positional argument: 'y'


add(*(4,5))

9

t=(4,5)
add(t[0],t[1])

9

add(*t)

9

add(*[4,5])

9

add(*{4,5})

9

add(*range(1,3))

3

  d = {‘x’: 5, ‘y’: 6}
  add(**d)

 

  11

 

  add(**{‘a’: 5, ‘b’: 6})

  TypeError: add() got an unexpected keyword argument ‘a’

 

  add(*{‘a’: 5, ‘b’: 6})

  ‘ab’

版权声明:本文为xpc51原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/xpc51/p/11468462.html