函数形参与实参*与**

1.什么是函数

  实现某个功能的代码的集合体

2.为什么需要函数

  代码结构不清晰,可读性差

  冗余度高

  扩展性差,可维护性差

3.定义函数

  def 函数名(参数1,...,参数n)

  '''

    函数的相关信息,称为文档注释

  '''

  函数功能的具体实现代码

   return 值

   可选:注释 return 参数,(函数体可以用pass来代替)

 

  函数的三种分类

    1.有参函数

      当函数的函数体执行过程中需要外部数据参与运算,才能完成功能时,就定义为有参

    2.无参函数

      当函数的函数体执行过程中不需要任何外部数据参与运算,就定义为无参

    3.空函数

      函数中不包含函数体就称之为空函数

      调用空函数是没有任何意义的,主要是用在编写代码的初期,用于定义程序的结构

4.调用函数

  函数名加括号

  print(函数名()) #打印返回值

  print(函数名)   #函数的内存地址

  函数名() * 10   #在表达式中调用函数

 

5.函数的返回值

  可以一次性return 多个值

 

  什么用返回值:当调用者需要拿到一个明确的结果时

  不写return 返回一个None

  return 返回一个None

  函数执行过程中 一旦遇到return 立马返回,后续代码都不执行

 

  当一次性返回值是多个值时 会自动把这些值打包到元组中

  可以直接队函数的返回值金星解压赋值

    

 

定义阶段

  1.申请内存空间,将函数体的代码存储到内存中

  2.将函数的内存地址。与函数名进行绑定

  定义阶段不会立即执行函数体的代码,但是会检测语法

调用阶段

  1.通过函数名找到函数的内存地址

  2.加括号触发函数体的执行

----------------------------------------------------------

 

函数参数详解

  形参与实参

    形参即形式参数,就是在定义函数时,括号中指定的参数,本质就是一个名字

      例如:

        def func1(a,b)  #a,b就是形式参数  a=1,b=2

          print(a)

          print(b)

        func1(1,2)  #1,2就是实参

 

    实参即实际参数,指的是在调用函数的时候传入的参数,是一个实际的值

   在调用函数时就会自动把形参(变量名)和实参(值)进行绑定,

   在函数调用结束之后绑定关系就解除了

 

  位置参数(用的最多)

    '''

      根据调用阶段,参数分为两类 形参和实参

      所以对应的位置参数也有两种:

        位置形参

        

        位置实参

      位置,指的是顺序,从左往右来定义的参数就是位置(顺序)参数

      需要注意的是:

        只要是定义了的位置形参都必须被传值

        位置形参的数量与位置实参的数量必须一致,不能多传,也不能少传

        实参会按照传入的位置依次赋值给形参

    '''

def func(a,b,c):   #abc都是位置形参

  print(a,b,c)

func(1,2,3)      #1,2,3都是位置实参

 

def register(name,password,sex):

  print("my name is %s pwd:%s sex:%s" % (name,password, sex))

register("virgil","123","man")

 

  关键字参数

    关键字实参

    在调用函数时,指名道姓的为形参赋值就称之为关键字参数

  其优点是:

    可以打破传入参数的顺序,可以不与形参顺序相同

  注意:

  1.不管以什么样的方式传值,每一个形参都必须被传值

  2.关键字参数必须位于位置参数的后面

  3.不能为同一个参数传多次值

  4.使用关键字传参时,实参的名字必须与形参的名字匹配

 

  到底是位置参数还是关键字参数 由实参决定

 

'''

def func(a,b,c)

  print(a)

  print(b)

  print(c)

func(1,2,c = 3)  #与位置参数没有区别

func(c = 3,1,2)  #语法错误 关键字参数出现在了位置参数的前面

func(c = 3,a = 1,b = 2)  #可以打破位置参数的顺序限制

'''

注册功能:

def register(name,pwd)

  print("name is",name)

  print("password is",pwd)

register(pwd = '123',name = 'virgil')

 

'''

  默认形参

   在定义时,就已经为形参指定了一个值,那这个形参就称之为默认形参

  特点:

    在调用是可以不用为默认形参传值,使用这个参数时就是默认值

    当然也可以传值,这样的话内部使用的就是你传入的值

  场景:

    当函数中的某一形参经常出现重复的值时,就可以将其定义为默认形参,

    可以简化调用代码

 

需要注意:

  1.默认形参必须放在非默认形参的后面

  2.默认形参的值在定义时就已经固定了

  3.不应该将默认形参的默认值设置为一个可变类型

  会导致 每次函数调用都会共用同一个默认参数,我们应该将函数设计为独立的功能,每次调用互不干扰

  只能是 int float str tuple 

'''

def reg(name,age,sex="woman"):

  print(name,age,sex)

res("rose",18)

res("lady",22)

res("Trish",26)

---------------------

def regl(name,sex,hobby):

  

  print(name,sex)

  print(hobby)

regl('virgil','man','sport')

regl('Dante','man','play')

 

  可变长参数(重难点)

'''

  可变长参数指的是,可以传任意个数的实参

  传入实参是为了给形参来使用,意味着必须让形参也具备可以接受任意个数的实参的能力

  也就是*和**

    带*的形参

    带*的形参表示可以接收任意个数的实参,接收到的实参会被打包成元组类型

    形参的名字可以随意,但建议用args 是arguments的缩写

 

    带*的实参

    在实参前面加*,会自动将*后的值,打散("abc"打散成了"a","b","c")

    

    带*的形参不能接收关键字实参

    

      位置形参与 可变长形参混合使用

      当可变长形参出现在了位置形参的前面时,那么后面的位置形参必须以关键字实参来传入

      当可变长形参出现在位置形参后面,会先按照顺序给前面的位置形参赋值,最后剩余的就赋值给可变长args

    

      **的使用

       形参中如果带有**,会把关键字实参打包成字典类型传入

       只能接收多出来的关键字实参

 

    实参中带**,会把**后的字典(也必须是字典类型)打散成关键字实参(**{"a":1})打散为 a=1

    

    * 和 **可以为函数预留扩展空间,后期可以根据需求增加参数,而且旧的函数调用方式也不会出现问题

    简单地来说就是提高函数的扩展性

 

'''

def func(*args):

func(1)

func(1,2)

func(1,2,3)

 

def func(a,b,c)

  print(a,b,c)

func(1,2,*3)  #*会将后面的字符串里面的数据打散

                     # iterable 可迭代的,只要是可以被for in 循环用的都是可迭代的 字符串 列表 元组 字符串 集合

 

 

 

def func(*args,a,b)

  print(a,b,args)

func(1,2,3,a=4,b=5)

 

先为前面的位置形参赋值,后面的多余的关键字参数赋值给**

**不能接收位置实参

def func (a,c,**b):

func(a = 100 , s = 100 , c = 'abc')       #结果  1  abc   {'s' : 100}

 

def func(a=1,b=2,**kwargs)

  print(a,b,kwargs)

func(a = -1 , b = -2 , s= 10)

  

 实参中带**

def func(name,sex):

  print(name,sex)

func(**{"name":"virgil","sex":"man"})    # func(name = "virgil")

 

# 写一个带有可变长的位置形参函数

def func(name,pwd,**kwargs):

  if name == 'virgil' and pwd == '123' and:

    if 'phone' in kwargs:

      if ukwargs['phone'] == '110':

        print('登录成功!')

    else:

        print('请传入手机号验证!')

    print('登录成功!')

  else:

    print('登录失败!')

func('virgil','123',phone = '110')

 

该方式可以接受任意个数的位置实参和关键字实参但要注意顺序,位置实参必须在关键字之前

def inner(name,sex,age)

  print(name,sex,age)

 

def outer(*args,*kwargs):

  print(args)

  print(kwargs)

  inner(*args,**kwargs)   #inner(1,2,3,100,a=10,b=20)

 outer(1,2,3,100,a=10,b=20)

#上述写法 可以将outer接收到的所有参数 原模原样的传给inner函数

 

 

 

 

 

 

 

 

 

 

 

 

 

 

    

posted @ 2019-01-11 13:16  -Rye-  阅读(438)  评论(0)    收藏  举报