Python-函数

函数

Python函数:

  由诺干个语句组成的语句块、函数名称、参数列表构成,它是组织代码的最小单元,完成一定的功能

 

函数的作用:

  结构化编程对代码的最基本的封装,一般按照功能组织一段代码

  封装的目的是为了复用,减少冗余代码

  代码更叫的简洁,易读性强

 

函数的分类:
  内键函数,如:print()、max()、int()等

  库函数,如:math.ceil()等

  自定义函数,使用def关键字定义

 

函数的定义

def 函数名(参数列表):
    函数体(代码块)
    return 返回值 #不写默认返回None,写则返回定义的值

函数名就是标识符,字母数字下划线,不能以数字开头

语句块必须缩进,约定为4个空格

Python的函数若没有return语句,会隐式返回None值

定义中的参数列表为形式参数,简称形参

 

函数的调用

函数定义只是声明了一个函数,它不会被执行,需要调用才能执行

调用的方式,就是函数名叫小括号,如有必要则传参数到小括号内

调用时写的参数是实际参数,简称为实参

def add(x,y): #函数定义
    result = x + y  #函数体
    return result #返回值
out = add(4,5) #函数调用,可能有返回值,使用变量接收这个返回值
print(out) #print函数加上括号也是函数调用

上面是定义一个函数add,函数名是add,能接收两个参数

该函数计算的结果通过返回值返回,需要return语句

调用格式,通过函数名的add()加两个参数,返回值可使用变量接收

函数名也是标识符,返回值也是值

定义需要在调用前,也就是说调用时已经被定义过,否则抛异常NameError

函数式可调用的对象,使用内嵌函数callable(函数名)返回True or False 

 

函数参数

函数在定义时要约定好形式参数,调用时也是要提供足够的实际参数,一般来说,形式参数和实际参数保持一致(可变参数除外)

 

传参方式:

  1、位置传参

    定义时def fn(x,y),调用时fn(1,2)按照参数定义的顺序传入参数

  2、关键字传参

    定义时def fn(x,y),调用时fn(x=1,y=2),使用形参的名字来传入实参的方式,如果使用了形参名字,那么传参顺序可以调换都行

  

  要求位置参数必须在关键字参数之前传入,位置参数是按位置对应的

示例:

#define 定义函数  
def add(x,y): #有参数函数,函数名、参数列表,x,y是在函数定义是,代表未来使用的变量,形式上的变量,称为形式变量,
    print(x,y)
    a = x + y
    return a #可以有n条return语句,如果没有return,则返回None

传参:
add(1,2)
add(x=1,y=2)
add(1,y=2)
add(y=2,x=1)
add(y=2,1) #错误传参,位置参数不能放在关键字参数后

 

参数缺省值

缺省值也称之为默认值,可以在函数定义时,为形参增加一个缺省值,其作用:

  1、参数的默认和可以在未传入足够的实参的时候,对没有给定的参数赋值为默认值

  2、参数非常多的时候,并不需要用户输入所有的参数,简化函数的调用

def add(x=4,y=5): #缺省值,缺省值必须在关键参数之前
    print(x,y)
    return x+y

#调用
add(),add(10),add(x=5),add(x=10,y=10),add(y=20,x=93),add(6,y=10) #位置传参需要在关键字传参前面 add(x=6,10),错误写法

 

可变参数

def sum(iterable):
    print(type(iterable))
    s = 0 
    for x in iterable:
        s += x
    return s 
sum(1,2,3) #错误的传参方式:sum() takes 1 positional argument but 3 were given
sum([1,2,3]),sum(range(5)) # (6,10)需要填入一个可迭代对象

可变位置形式参数

def sum1(*iterable): #可变位置形参,接收0~n 个参数,只接受位置传参,返回时tuple元组,不可变,可迭代
    print(type(iterable),iterable)
    s = 0 
    for x in iterable:
        s += x
    return s 
sum1(),sum1(1,2,3),sum1(1,2,0)#sum1(range(5)) sum1([1,2,3]) #这两种为错误写法 ,只接收位置传参,可使用参数解构 sum1(*range(5)) sum1(*[1,2,3])

 

 1、可变位置参数

  在形参前使用*表示该形参是可变位置参数,可以接收多个实参

  它将收集来的实参组织到一个tuple元组中

2、可变关键字参数

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

  它将收集来的实参组织到一个dict字典中

 

def test(**kwargs): #可变关键字传参 能接收n个参数,返回一个全新的字典
    print(kwargs)
    kwargs['d'] = 1000
    print(kwargs)

test(),test(a=1,b=2),test(a=10,b=20,d=10) 
#输出
{}
{'d': 1000}
{'a': 1, 'b': 2}
{'a': 1, 'b': 2, 'd': 1000}
{'a': 10, 'b': 20, 'd': 10}
{'a': 10, 'b': 20, 'd': 1000}

def login(host,port,**kwargs):
    print(host,port)
    print(kwargs)
    protocol = kwargs.get('protocol','https')
    print(protocol)

调用: login(
'127.0.0.1',80,username='alren',protocol='http') 输出: 127.0.0.1 80 {'username': 'alren', 'protocol': 'http'} http

 

总结

有可变位置参数和可变关键字参数

可变位置参数在形参前使用一个*号表示

可变关键字参数在形参前使用两个**号表示

可变位置参数和可变关键字参数都是可以收集诺干个实参,可变位置参数收集形成一个tuple()元组 ,可变关键字参数收集形成一个dict字典

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

def fn(x,y=5,*args,**kwargs):
    print(x,y)
    print(args)
    print(kwargs)
    print()
#调用
fn(1),fn(1,2),fn(1,2,3,4,5),fn(1,(2,3),[3,4,5]),fn(1,2,3,4,5,a=1)
fn(x=1,6,1,1,2,a=1,b=2) #错误写法 可变位置参数需要在可变关键字参数之前
fn(1,y=6,1,1,2,a=1,b=2) #正确

 

 

keyword-only参数

在Python3开始引入了keyword-only参数,在形参定义时,在一个*号之后,或在一个可变位置位置参数之后出现的普通参数,就称之为keyword-only参数

v#keyword-only
def fn(x=4,*args,y,**kwargs):
    print(x,y)
    print(args)
    print(kwargs)
    print()

#调用
fn() missing 1 required keyword-only argument: 'y' #错误,y必须使用keyword关键词传参

#如下正确
fn(y=200),fn(1,y=100),fn(1,2,3,4,y=12,z=100)

#输出
1 12
(2, 3, 4)
{'z': 100}

 keyword-only参数则表示这个参数只能用关键字传参,keyword-only还有另外一种表示方式,一个*号,后面接普通参数

def sub(*,x,y): #x,y为keyword-only参数     
    print(x,y)

def fn5(x,y,z=100,*,m,n=200,**kwargs): #当不需要可变位置参数时可这么写
    pass

#调用
sub(x=1,y=2)
fn5(1,2,m=100)

position-only参数

在Python3.8引入了position-only位置参数,寓意只能通过位置传参。

def sub(x,y,/): #x,y为position-only参数     
    print(x,y)

参数规则

  参数列表参数 一般顺序是:普通参数,缺省参数,可变位置参数,keyword_only (可带缺省值),可变关键字参数。

 

参数解构

在给函数提供实际参数的时候,可以在可迭代对象前使用*或**来进行结构的解构,提取出其中所有的元素作为函数的实参

  使用*解构成位置传参

  使用**解构成关键字传参

  提取出来的元素数目要和参数的要求匹配

示例:

#参数结构
def add(x,y):
    print(x,y)
    return x+y

#调用
add(*'ab'),add(*b'ab'),add(*(4,5)),add(*[4,5]),add(*{7,8}),add(*{'a':100,'b':200}.keys())#参数解构 ,add(*{7,8})无序
def sum(*iterable):
    print(type(iterable))
    s = 0 
    for x in iterable:
        s += x
    return s

#调用
sum(1,2,2),sum(*[1,2,3]),sum(*range(10))

 

posted @ 2020-04-10 22:24  Alrenn  阅读(244)  评论(0)    收藏  举报