Python学习之---自定义函数(def())的使用与相关操作

Python学习之—自定义函数(def())的使用+相关操作

知识索引
在这里插入图片描述
首先牢记:
关键字参数不可以在位置参数和普通参数的前面
可变关键字参数,不可以在可变位置参数和普通参数前面.
重要的事说三遍!!!牢记~~~
这是后面判断定义的函数和函数调用是否正确的重要方法,往往会忘记.

函数:

数学定义
y=f(x),y是x的函数,x是自变量.

Python函数
● 由若干语句组成的语句块,函数名称,参数列表,它是组织代码的最小单元
● 完成一定功能
函数作用:
● 结构化编程对代码的最基本的封装,一般按照功能组织一段代码
● 封装目的是为了复用,减少冗余代码
● 代码更加美观,可读易懂!
分类:
● 内荐函数 如max() reverse()
● 库函数 如math() ceil()
● 自定义函数 使用def()关键字定义

函数定义

def function name (parameter):
   function body
   return

● 函数名就是标识符,命名要求与变量命名要求一样
● 语句块必须缩进,预定4个空格
● Python的函数若没有return语句,会隐式返回一个None值
● 定义中的参数列表称为形式参数,只是一种符号标识符

函数调用

● 函数定义,只是声明了一个函数,它不能被执行,需要调用执行
● 调用的方式,就是函数名后加上小括号,如有必要在括号内填写上参数
● 调用时写的参数是实际参数,是实实在在传入的值,简称实参

def add(x,y):  #x y 为形式参数,也是标识符.add指向函数对象
     return x +y  # 需要返回值就用return 
add(4,5)     #函数的调用,函数名后使用小括号,小括号内填入实际实实在在的参数,简称实参.  
add(4,5),add('a','b'),add([0],[2])  
>>> (9, 'ab', [0, 2])  

函数本身是一个callable()[可调用对象]
callable(add) #返回是否是可调用.True False

函数参数

函数在定义时要约定好形式参数,调用时也提供足够的实际参数,一般来说,形参和实参个数需要一致.(可变参数除外)
传参方式
(1) 位置传参
定义def fun(x,y,z),调用 fun(1,2,3),按照参数定义顺序传入实参.
(2) 关键字传参
定义时def fun(x, y, z),调用使用 fun(x=1, y=3, z=5),使用形参的名字来传入实参的方式,如果使用了形参名字,那么传参顺序就可和定义顺序不同
要求位置参数必须在关键字参数之前传入,位置参数是按位置对应的

def fun(x, y, z):  
     pass
fun(1,2,3)  
fun(x=10,z=15,y=20)#  关键字传参不考虑传参的顺序,但个数要一致.可以用位置和关键字一同传参.
fun(12,y=20,z=10)# 关键与位置传参组合使用

def add(x=20,y):#  错误 关键字缺省值不能写前
     return x+y
add(y=10,10) #错误关键字传参不能写前面  

函数缺省值
★缺省值也称为默认值,可以在函数定义时,为形参增加一个缺省值。
其作用:
● 参数的默认值可以在未传入足够的实参的时候,对没有给定的参数赋值为默认值
● 参数非常多的时候,并不需要用户每次都输入所有的参数,简化函数调用

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

测试调用

add()、add(x=5)、add(y=7)、add(6, 10)、add(6, y=7)、add(x=5, y=6)、add(y=5, x=6)、
add(x=5, 6)、add(y=8, 4)、add(11, x=20)#报错么????

其中:

add(x=5, 6)、add(y=8, 4)、add(11, x=20) 

这三个调用时会报错,原因是什么呢?
首先,关键字传参不允许在位置传参之前,这个前面有写,再者,同一个参数只能传参一次,在add(11,x=20)中,函数默认的将11传给了x,后面又传一个x=20,这两个相违背,所以会报错.
能否这样定义 def add(x, y=5) 或 def add(x=4,y)— ?
参数缺省值举例:

#定义一个函数login,参数名称为host、port、username、password
def login(host='127.0.0.1', port='8080', username='wayne', password='magedu'):
     print('{}:{}@{}/{}'.format(host, port, username, password))
login()
login('127.0.0.1', 80, 'tom', 'tom')
login('127.0.0.1', username='root')
login('localhost', port=80, password='com')
login(port=80, password='magedu', host='www')  

可变参数

可变位置参数
在形参前使用 * 表示该形参是可变位置参数,可以接受多个实参 他将收集来的实参组织到一个tuple中.
示例:

def sum(iterable):
    result =0
    for x in iterable:
        result += x
    return result  
sum([1,2,3])# 这种参数传参需要用一个可迭代对象传参,只是一个参数

def sum(*iterable):#可变的位置参数,将收集的数据放置在元组中
    
    result=0
#     print(type(iterable),iterable)
    for x in iterable:
        result += x
    return result
sum(1,2,3)   
>>> 8   #直接传入多个参数,先封装成一个元组,这里是多个参数.注意二者的不同用法

可变关键字参数
在形参前使用 ** 表示该形参是可变关键字传参,可以接受多个关键字传参.

def showconfig(**kwargs):
    print(type(kwargs))
    print(kwargs)
showconfig(a=1,b=2)  
>>>
<class 'dict'>
{'a': 1, 'b': 2}

可变位置参数与可变关键字参数的混合使用
可以定义为下列方式吗?

def showconfig(username, password, **kwargs)
def showconfig(username, *args, **kwargs)
def showconfig(username, password, **kwargs, *args) # ?#  不可以!!!!

总结:
● 有可变位置参数和可变关键字参数
● 可变位置参数在形参前使用一个星号*
● 可变关键字参数在形参前使用两个星号**
● 可变位置参数和可变关键字参数都可以收集若干个实参,可变位置参数收集形成一个tuple,可变关键字参数收集形成一个dict
● 混合使用参数的时候,普通参数需要放到参数列表前面,可变参数要放到参数列表的后面,可变位置参数需要在可变关键字参数之前

举例;

def fn(x, y, *args, **kwargs):
     print(x, y, args, kwargs, sep='\n', end='\n\n')
fn(3, 5, 7, 9, 10, a=1, b='abc')# x=3,y=5,(7,9,10 )作为一个元组,剩下的作为字典
fn(3, 5)# 可以,可变参数可以是0个或多个
fn(3, 5, 7)#可以
fn(3, 5, a=1, b='abc')#可以,可变位置参数为0
fn(x=3, y=8, 7, 9, a=1, b='abc') # ? 不可以,关键字参数在普通参数前面
fn(7, 9, y=5, x=3, a=1, b='abc') # ?同样不可以,定义重复

keyword-only 参数

在Python3之后,新增了keyword-only参数。
keyword-only参数:在形参定义时,在一个*星号之后,或一个可变位置参数之后,出现的普通参数,就已经不是普通的参数了,称为keyword-only参数。
举例:

def fn2(*args,x):
    print(x)
    print(args) 
fn2(1,2,3,4)#报错,因为可变位置参数尽可能多的收集所有的位置参数.后面的x得不到数据,所以只能用keyword-only进行传参.  

错误定义举例:

def fn2(a,b,*args=(10,20),**kwargs):#  报错,可变位置参数,本身就可以收集0个元素,不需要缺省值,因此会语法报错.
   pass  
def fn(**kwargs ,a,b,x=5)  #关键字参数在后

keyword-only参数另一种形式

def fn(a,b,*,z,**kwargs): # * 号后所以的普通参数都成了keyword-only的参数了.
    pass
fn(1,2,z=6)

参数混合使用练习:

# 可变位置参数、keyword-only参数、缺省值
def fn(*args, x=5):
     print(x)
     print(args)
fn() # 等价于fn(x=5)
fn(5)
fn(x=6)
fn(1,2,3,x=10)
# 普通参数、可变位置参数、keyword-only参数、缺省值
def fn(y, *args, x=5):
    print('x={}, y={}'.format(x, y))
    print(args)
fn() #   报错, y 取不到值,报错 
fn(5)# y=5,*args 为空元组,x=5  缺省值
fn(5, 6)  #y =5,6给元组,x=5缺省值
fn(x=6) # 报错,y无参数
fn(1, 2, 3, x=10)# 1给y,2,3给元组,x=10,缺省值
fn(y=17, 2, 3, x=10) #  报错,关键字传参在其他之前,返回顶端,牢记!!!
fn(1, 2, y=3, x=10) #报错,y重复定义.

参数规则

参数列表参数一般顺序是:普通参数、缺省参数、可变位置参数、keyword-only参数(可带缺省值)、可变关键字参数。
注意:
● 代码应该易读易懂,而不是为难别人
● 请按照书写习惯定义函数参数
● 定义最常用参数为普通参数,可不提供缺省值,必须由用户提供。注意这些参数的顺序,最常用的先定义
● 将必须使用名称的才能使用的参数,定义为keyword-only参数,要求必须使用关键字传参
● 如果函数有很多参数,无法逐一定义,可使用可变参数。如果需要知道这些参数的意义,则使用可变关键字参数收集

参数解构

参数解构原则:
在给函数提供实参的时候,可以在可迭代对象前使用 * 或者 ** 来进行结构的解构,提取出其中所有元素作为函数的实参
● 使用 * 解构成位置传参
● 使用 ** 解构成关键字传参
● 提取出来的元素数目要和参数的要求匹配
举例:

def add(x,y):
     return x+y
add(*[4,5]),add(*{4,5}),add(*(4,5)),add(*range(4,6))  
*{'a':1,'b':2}.items()  #参数解构只能写在传实参的地方才可以使用  
add(*{'a':2,'b':3)
>>>ab #默认的会按照字典的key进行解构,数字的相加,字符串按照字符串相加.
add(**{'a':1,'b':2})  #解构成a=1,b=2 ,将字典结构成关键字传参,除了字典以外,不能使用两个星号进行传参.  
add(**{'x':1,'y':2})或者add(*{'a':1,'b':2}.values())  #用**解构,按关键字传参需要传入的参数一样.
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值