zoukankan      html  css  js  c++  java
  • Python-函数

    阅读目录:

      1、函数

      2、函数定义,调用

      3、函数参数

      4、函数参数默认值

      5、可变参数

      6、函数参数

      7、参数解构

    内容:

    1、函数

      函数:

        数学定义:y = f(x) ,y 是 x 的函数,x  是自变量。 y = f(x0,x1...,xn).

        Python 函数:

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

      函数的作用:

        • 结构化编程对代码的最基本的封装,一般按照功能组织一端代码。
        • 封装的目的为了服用,减少冗余代码
        • 代码更加简洁美观,可读易懂

      函数的分类:

        • 内建函数,如max()
        • 库函数,如 math.ceil()  使用需要到入库 math

    2、函数定义,调用

      def 语句定义函数:

        def  函数名(参数列表):

           函数体(代码块)

           [ return 返回值 ]

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

        函数调用:

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

          调用方式:就是函数名加上小括号,括号内写上参数

          条用时,写的参数是实际参数,是实实在在传入的值,简称 实参

        函数举例

          def add(x, y):

            result = x + y

            return result

          out = add(4, 5)

          print(out)

          • 上面只是一个函数的定义,有一个函数叫做add,接受2 个参数
          • 计算的结果,通过返回值返回
          • 调用通过函数名 add加 2 个参数,返回值可使用变量接受
          • 定义需要在调用前,也就是说调用时,已经被定义过,否则抛 NameError 异常
          • 函数是可调用的对象,用 callable() ----callable(函数名)返回True 就是可悲调用的
          • print() 本身是没有 返回值 return
              • print(print(type(3)))
              • In [28]: print(print(type(3)))
                <class 'int'>
                None

          • 先定义 后调用

    3、函数参数

        参数调用时 传入 的参数 要和定义的个数相匹配(可变参数例外)

        ***位置参数:

          def f( x, y, z) 调用 f( 1, 2, 3)

          按照参数定义顺序传入实参

        ***关键字参数

          def f( x, y, z) 调用使用 f( x=1, y=2, z=3)

          使用形参的名字来出入实参的方式,如果使用了形参 名字,那么传参顺序就可和定义顺序 不同  

        传参:

          f(z = None, y=10, z=[1] )

          f((1,) , z=6,y = 4.2)

          f(y=4,z=7, 2) : 错误的传参,位置参数,不能放在关键字参数之后

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

    4、函数参数默认值:

        参数默认值(缺省值)

            定义时,在形参后跟上一个值

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

              return x + y        

     1 def  add(x=4, y=5):
     2     return x + y
     3 
     4 add(6,9) # 15
     5 add(6, y=7) # 13
     6 add(x=5) # 10
     7 add() # 9
     8 add(y=7) # 11
     9 add(x=5, 6) # 语法错误
    10 add(y=9, x=3)# 12
    11 add(x=1, y=2)# 3
    test def add(x=4, y=5)
     1 def  add(x=4, y): # non-default argument follows default argument
     2     return x + y
     3 
     4 # add(6,9) # 15
     5 # add(6, y=7) # 13
     6 # add(x=5) # 10
     7 # add() # 9
     8 # add(y=7) # 11
     9 # add(x=5, 6) # 语法错误
    10 # add(y=9, x=3)# 12
    11 # add(x=1, y=2)# 3
    test def add(x=4, y):

      注:  def  add(x=4, y) 定义时错误的,缺省参数不能放在非缺省参数之前

        作用:

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

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

        举例:

    def login(host='localhost',username='jacke',password='ssss'):
        pass

    5、可变参数

      有多个数,需要累加求和

    1 def add(nums):
    2     sum = 0
    3     for x in nums:
    4         sum += x
    5     return sum
    6 
    7 add([1,2,3]) # 6
    8 add((2,3,4))# 9

          传入一个可迭代对象,迭代元素求和

      可变参数:

        一个形参可以匹配任意个参数

        ***位置参数的可变参数:

     1 def add(*nums):
     2     sum = 0
     3     print(type(nums))
     4     for x in nums:
     5         sum += x
     6     print(sum)
     7 
     8 add(3,4,6)
     9 
    10 # <class 'tuple'>
    11 # 13

          注:        

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

            收集多个实参为一个tuple

        ***关键字参数的可变参数: 只收集 关键字参数            

     1 def showconfig(**kwargs):
     2     for k,v in kwargs.items():
     3         print(k,v)
     4     print(kwargs)
     5     kwargs['a'] = 0
     6     print(kwargs)
     7 showconfig(a=1, b=3, c=5)
     8 
     9 # a 1
    10 # b 3
    11 # c 5
    12 # {'a': 1, 'b': 3, 'c': 5}
    13 # {'a': 0, 'b': 3, 'c': 5}
    **kwargs

           注:

             形参前面使用** 符号,表示可以接受多个关键字参数

             收集的实参名称和值 组成一个字典 ,这个字典可以修改

        ***可变参数混用:

            配置信息打印

    1 def showconfig(username, password, **kwargs):
    2     
    3 def showconfig(username, *args, **kwargs):
    4     
    5 def showconfig(username, password, **kwargs, *args): # 错误,可变关键字参数只能在可变位置参数之后

        总结:

        • 有位置可变参数和关键字参数可变参数
        • 位置可变参数在形参前使用一个 星号 *
        • 关键字可变参数在形参前使用两个星号**
        • 位置可变参数和关键字可变参数都可以收集若干个实参,位置可变参数收集形成一个 元组,关键字可变参数收集形成一个 字典
        • 混合使用参数的时候,可变参数要放到单数列表的最后,普通参数需要放在参数列表前面,位置可变参数需要在关键字可变参数之前

    练习:

     1 def fn(x, y, *args, **kwargs):
     2     print(x)
     3     print(y)
     4     print(args)
     5     print(kwargs)
     6    
     7 # fn(3, 5, 7, 9, 10, a=1, b='python')# 正确
     8 
     9 # # 因为之前位置参数已经给了,然后在给值就重复了
    10 # fn(7, 9, x=1, a=1, b='python') # fn() got multiple values for argument 'x'
    11 
    12 
    13 fn(2, a=1, b=2, y=1)# 正确
    test 混合使用
     1 def fn(*args, x, y,  **kwargs):
     2     print(x)
     3     print(y)
     4     print(args)
     5     print(kwargs)
     6     
     7 fn(3,2,5) #keyword_only meiyou 给定
     8 fn(3,5,a=1,b=3) #keyword_only meiyou 给定
     9 fn(3,4,x=2,y=3,a=1) # 正确
    10 
    11 # 2
    12 # 3
    13 # (3, 4)
    14 # {'a': 1}
    test 混合使用

        *** keyword-only 参数 (python 3 加入的)

          如果 在一个 星号* 参数后,或者一个位置可变参数后,出现的普通参数,实际上已经不是普通参数了,而是keyword-only 参数

          举例:只能通过关键字传参,要不就给缺省值

     1 def fn(*args, x):
     2     print(x)
     3     print(args)
     4 
     5 # fn(3,5)
     6 # fn(3,4,5)
     7 fn(3,4,x=2)
     8 
     9 # 2
    10 # (3, 4)
    举例

          def fn( **kwargs,  x):  直接报语法错误,可以理解为开挖如果是,会截获所有的关键字参数,就算写了 x=5, 也会被 可变关键字参数接受,所以x 永远得不到这个值。

          def fn(*args, x, y=100):正确

          

          keyword-only 参数的另一种形式:

    1 def fn(*, x, y):# 逗号不能少!!!!
    2     print(x, y)
    3 
    4 fn(x=3, y=5)

          注: *  之后,普通形参都变成了必须给出的keyword-only 参数

        

        可变参数和参数默认值:    

     1 def fn(*args, x=5):
     2     print(x)
     3     print(args)
     4     
     5 fn() # 等价fn(x=5)
     6 fn(5) # 5 给了前者
     7 # 5
     8 # (5,)
     9 fn(x=6)
    10 # 6
    11 # ()
    12 fn(1,2,3,x=10)
    13 
    14 
    15 
    16 
    17 def fn(y ,*args, x=5):
    18     pass
    19 fn()# y没有
    20 fn(y=17,2,3,x=1)# 位置参数要放在关键字参数之前  y=17,2,3 ----2,3,y=12 但是还是不对,因为y已经给了2,重复了
    举例

    6、函数参数

      参数规则:

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

        def f(x, y, z=3, *arg, m=4,n,**kwargs):

            pass

        注意:

          代码应该易读易懂,按照书写习惯定义函数参数

       参数规则举例:

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

     1 def connect(host='localhost', port='3306', user='admin',password='admin',**kwargs):
     2     print(host, port)
     3     print(user,password)
     4     print(kwargs)
     5     
     6 connect(db='cmdb')
     7 connect(host='192.168.12.1', db='cmdb')
     8 connect(host='192.168.12.1', db='cmdb', password='dasda')
     9 '''
    10 localhost 3306
    11 admin admin
    12 {'db': 'cmdb'}
    13 192.168.12.1 3306
    14 admin admin
    15 {'db': 'cmdb'}
    16 192.168.12.1 3306
    17 admin dasda
    18 {'db': 'cmdb'}
    19 '''
    test

    7、参数解构 :只能用在函数传参中,区别 普通的解构

    1 def add(x, y):
    2     return x + y
    3 add(4,5)
    4 add([4,5][1],(1,2)[1])
    5 add(*[4,5])
    6 add(*(4,5))
    7 add(*{4,5})
    8 add(*'45')
    9 add(*range(100, 102))
    test-解构
    1 def add(x, y):
    2     return x + y
    3 
    4 add(*{'a':1,'b':2}) #'ab'
    5 # add(**{'a':1,'b':2}) # 报错
    6 add(*{'x':1,'y':2}) #'xy'
    7 add(**{'x':1,'y':2}) # 3
    字典参数解构

        参数解构:

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

        参数解构 和可变 参数

          给函数提供实参的时候,可以再集合类型前使用* 或 **

     1 def add(*iterable):# 注意,别犯傻,这个是 *args
     2     print(iterable )
     3     result = 0
     4     for x in iterable:
     5         result += x
     6     return result
     7 
     8 # add(1,2,3)
     9 
    10 # add(*[1,3,4])
    11 
    12 # add(*range(10 ))
    13 
    14 add(range(10)) # 报错,将range(10)给了 iterable这个元组 (range(0, 10),)
    15     # 虽然这个元组可迭代,但是就一个元素,x + 0 是什么鬼?
    test
    为什么要坚持,想一想当初!
  • 相关阅读:
    P1478 陶陶摘苹果(升级版)
    洛谷 P1008 三连击
    1412:二进制分类
    1411:区间内的真素数
    判断素数
    关于小数
    一本通题库1159斐波那契数列
    一本通题库1161转进制
    一本通题1051
    基础算法——数据排序——冒泡
  • 原文地址:https://www.cnblogs.com/JerryZao/p/9513984.html
Copyright © 2011-2022 走看看