Python函数

函数介绍

定义:  函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可。

特性:减少重复代码、使程序变的可扩展、使程序变得易维护。

函数的结构与调用

函数的结构

def 函数名():

    函数体

def 关键词开头,空格之后接函数名称和圆括号(),最后还有一个":"。

def 是固定的,不能变,他就是定义函数的关键字。

空格 为了将def关键字和函数名分开,必须空(四声),当然你可以空2格、3格或者你想空多少都行,但正常人还是空1格。

函数名:函数名只能包含字符串、下划线和数字且不能以数字开头。虽然函数名可以随便起,但我们给函数起名字还是要尽量简短,并且要具有可描述性。

括号:是必须加的,括号是参数。

下面的函数体一定全部都要缩进,这代表是这个函数的代码。

#函数定义
def mylen():
    """计算s1的长度"""
    s1 = "hello world"
    length = 0
    for i in s1:
        length = length+1
    print(length)

函数的调用

使用函数名加小括号就可以调用了 写法:函数名() 这个时候函数的函数体会被执行

通过上面的动态图大家可知,只有解释器读到函数名() 时,才会执行此函数,如果没有这条指令,函数里面即使有10万行代码也是不执行的。

而且是这个指令你写几次,函数里面的代码就运行几次。

函数的注释

注释:每一个函数都应该对功能和参数进行相应的说明,应该写在函数下面第一行。以增强代码的可读性。

def func():
     '''
     这个函数实现了什么功能
     参数1:
     参数2:
     :return: 是字符串或者列表的长度
     '''
     pass

函数的返回值

没有返回值

不写返回值(不写return)

#函数定义
def mylen():
    """计算s1的长度"""
    s1 = "hello world"
    length = 0
    for i in s1:
        length = length+1
    print(length)
 
#函数调用
str_len = mylen()
#因为没有返回值,此时的str_len为None
print('str_len : %s'%str_len)

注:不写return的情况下,会默认返回一个None:我们写的第一个函数,就没有写return,这就是没有返回值的一种情况。

只写返回值(只写return)

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

注:一旦遇到return,结束整个函数。

def ret_demo():
    print(111)
    return None
    print(222)
 
ret = ret_demo()
print(ret)

注:和上面的两种情况一样,我们一般不这样写。

返回一个值

# 函数定义
def mylen():
    """计算s1的长度"""
    s1 = "hello world"
    length = 0
    for i in s1:
        length = length + 1
    return length


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

注:1.可以返回任何数据类型  2.只要返回就可以接收到  3.如果在一个程序中有多个return,那么只执行第一个

返回多个值

def ret_demo2():
    return 1, ['a', 'b'], 3, 4  # 返回多个值,用多个变量接收


# 返回多个值,用一个变量接收
ret = ret_demo2()  # 相当:ret = (1, ['a', 'b'], 3, 4)
print(ret)

# 返回的多个值会被组织成元组被返回,返回几个值,就用几个变量接收
a, b, c, d = ret_demo2()  # 相当:a, b, c, d = (1, ['a', 'b'], 3, 4)
print(a, b, c, d)

函数的参数

我们告诉mylen函数要计算的字符串是谁,这个过程就叫做 传递参数,简称传参,我们调用函数时传递的这个“hello world”和定义函数时的s1就是参数。

# 定义函数时的s1,只是一个变量的名字,被称为形式参数,因为在定义函数的时候它只是一个形式,表示这里有一个参数,简称形参。  
def mylen(s1):
    """计算s1的长度"""
    length = 0
    for i in s1:
        length = length + 1
    return length


# 调用函数时传递的这个“hello world”被称为实际参数,因为这个是实际的要交给函数的内容,简称实参。
str_len = mylen("hello world")
print('str_len : %s' % str_len)

传递多个参数

参数可以传递多个,多个参数之间用逗号分割。

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

位置参数

站在实参角度

1、按照位置传值

就是从左至右,实参与形参一一对应。

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

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

 2、按照关键字传值

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

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

3、位置、关键字形式混着用

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 mymax(x,y):
    #此时x = 10,y = 20
    print(x,y)
    the_max = x if x > y else y
    return the_max

#调用mymax不传递参数
ma = mymax()
print(ma)

#结果
TypeError: mymax() missing 2 required positional arguments: 'x' and 'y'

默认参数

1、默认参数的定义

定义了默认参数后,在函数调用时不需要再传入,默认参数放在最后面

def info(name,age,country = 'CN'):   #country定义了一个默认参数
    print('姓名:{},年龄:{},国籍:{}'.format(name,age,country))

info('derek',22)     #调用时,没穿实参countrty,就用默认的参数

结果:姓名:derek,年龄:22,国籍:CN

2、参数陷阱

默认参数是一个可变数据类型

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


defult_param('小白')  # ['小白']
defult_param('小黑')  # ['小白', '小黑']

动态参数

动态参数分为两种:动态接受位置参数 *args,动态接收关键字参数**kwargs。

*args:动态接收位置参数

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

def fuck(name, age, *args):  # *args会把多传入的参数变成一个元祖形式
    print(name, age, args)


fuck('xiaobai', 20, '', '篮球')  # xiaobai 20 ('男', '篮球')

**kwargs:动态接收关键字参数

按关键字传值多余的参数都由kwargs统一接收,保存成一个字典的形式

# **kwargs
def fuck(**kwargs):  # **kwargs 会把多传入的参数变成一个dict形式
    print(kwargs)


fuck(name = 'xiaobai',age= 20)  # {'name': 'xiaobai', 'age': 20}

 注:形参的排序——1.位置参数(必须传)2.*args:可以接收任意多个位置参数 3.默认参数:可以不传 4.**kwargs:可以接收多个关键字参数

* 的魔性用法

聚合

在函数定义时,如果我只定义了一个形参称为args,只能当做一个位置参数对待,它只能接受一个参数。

def eat(args):
    print(args) 
eat('abcdef')  # abcdef

如果我给其前面加一个* 那么args可以接受多个实参,并且返回一个元组。 (**kwargs也是同理将多个关键字参数转化成一个字典返回)所以在函数的定义时: *起到的是聚合的作用。

打散

# 可迭代对象打散
print(*[1, 2, 3, 4, 5, 6])  # 1 2 3 4 5 6
print(*'asafasaffa')  # a s a f a s a f f a
s1 = 'alex'
l1 = [1, 2, 3, 4]
tu1 = ('小白', '小米', '小黑',)

def func(*args):
    print(args)  # ('a', 'l', 'e', 'x', 1, 2, 3, 4, '小白', '小米', '小黑')

func(*s1, *l1, *tu1)


# 字典的打散
dic1 = {'name': '小白', 'age': 18}
dic2 = {'hobby': '喝茶', 'sex': ''}

def func(**kwargs):
    print(kwargs)  # {'name': '小白', 'age': 18, 'hobby': '喝茶', 'sex': '男'}

func(**dic1, **dic2)

处理剩下的元素

除了在函数中可以这样打散,聚合外,函数外还可以灵活的运用:

# 之前的分别赋值
a,b = (1,2)
print(a, b) # 1 2
# 其实还可以这么用:
a,*b = (1, 2, 3, 4,)
print(a, b) # 1 [2, 3, 4]
*rest,a,b = range(5)
print(rest, a, b) # [0, 1, 2] 3 4
print([1, 2, *[3, 4, 5]]) # [1, 2, 3, 4, 5]

 

posted @ 2020-07-07 22:24  he。  阅读(111)  评论(0编辑  收藏  举报