Python函数、参数及参数解构

Python函数、参数及参数解构

函数

  • 数学定义:y=f(x),y是x的函数,x是自变量
  • Python函数
    1. 由若干语句块组成的语句块、函数名称、参数列表构成,他是组织代码的最小单元
    2. 完成一定的功能
  • 函数的作用
    1. 结构化编程对代码的最基本的封装,一般按照功能组织一段代码
    2. 封装的目的是为了复用,减少冗余代码
    3. 代码更加简洁美观、可读易懂
  • 函数的分类
    1. 内建函数,如max()、min()
    2. 库函数,如math.ceil

函数的定义、调用

  • def语句定义函数
    def 函数名(参数列表):
        代码块          #函数体
        [return 返回值]
    
    1. 函数名就是标识符,命名要求和标识符命名要求一致
    2. 语句块必须缩进,约定四个空格
    3. Python的函数没有return语句,隐式会返回一个None值
    4. 定义中的参数列表称为形式参数,只使一种符号表达,简称形参
  • 调用
    1. 函数定义,只是声明了一个函数,他不会被执行,需要调用
    2. 调用的方式,就是函数名加上小括号,括号内写上参数
    3. 调用时写的参数是实际参数,是传入给函数的值,简称参数
  • 函数举例
    def add(x,y):
        result = x + y
        return result
    out = add(4,5)
    print(out)
    1. 定义需要在调用前,也就是说调用时已经被定义过了,否则报错name is not defined
    2. 函数是可调用的对象,zaipython中有个内建函数callable() 可以查看标识符是否是一个可调用的对象
  • 函数参数
    1. 参数调用时传入的参数要和定义的参数个数相匹配(可变参数例外)
    2. 位置参数
      • def f(x,y,z) 调用使用f(1,3,5)
      • 按照参数定义顺序传入实参
    3. 关键字参数
      • def f(x,y,z) 调用使用f(x=1,y=3,z=5)
      • 使用形参的名字来传入实参的方式,如果使用了形参名字,那么传参顺序就可以和定义顺序不同
    4. 传参
      • f(z=None,y=10,x=[1])
      • f((1,),z=6,y=4.1)
      • f(y=5,z=6,2)
      • 要求位置参数必须在关键字参数之前传参,位置参数是按位置对应的
  • 函数参数默认值
    1. 参数默认值
      定义时,在形参后跟上一个值
      def add(x=4,y=5):
          return x+y
      测试调用: add(6,10)、add(6,y=7)、add(y=7)、add(x=5,6)、add(y=8,4)、add(x=5,y=6)、add(y=5,x=6)
      测试 def add(x=4,y)
    2. 作用
      • 参数的默认值可以在未传入足够的实参的时候,对没有给定的参数赋值为默认值
      • 参数非常多的时候,并不需要用户每次都输入所有参数,简化函数调用
    3. 举例:定义一个函数login,参数名host、port、username、password
      def login(host='127.0.0.1',port='3306',username='kx',password='7954321'):
          print('{}:{}@{}/{}'.format(host,port,username,password))
      
      测试调用
      login()
      login('127.0.0.1',80,'stephon','stephon')
      login('127.0.0.1',username='root')
      login('localhost',port=80,password='com')
      login(port=80,password='7954321',host='www')
  • 可变参数
    1. 问题:有多个数需要累加求和
      def add(nums):
          sum = 0
          for x in nums:
              sum += x
          return sum
      测试调用 add([1,3,5])、add((2,5,8))
      
      ==传入迭代元素,迭代元素求和==
    2. 可变参数:一个形参可以匹配任意个参数
    3. 位置参数的可变参数
      有多个数,需要累加求和
      
      def add(*nums):
          sum = 0
          print(nums)
          for x in nums:
              sum += x
          print(sum)
          
      测试调用add(3,6,9)
    4. 在形参前使用*标识改形参时可变参数,可以接受多个实参
    5. 收集多个实参为一个tuple
  • 关键字参数的可变参数
    1. 关键字参数的可变参数
      例子:  配置信息打印
      def shouconfig(**kwargs):
          for k,v in kwargs.items():
              print('{}={}'.format(k,v))
      测试调用
    2. 形参前使用**符号,标识可以接受多个关键字参数
    3. 收集的实参名称和值组成一个字典
  • 可变参数混合使用
    - def showconfig(username,password,**kwargs)
    - def showcofig(username,*args,**kwargs)
    - def showconfig(username,password,**kwargs,*args)
  • 总结
    1. 有位置可变参数和关键字可变参数
    2. 位置可变参数和关键字可变参数都可以收集若干个实参,位置可变参数手机实参形成元组,关键字可变参数收集实参形成一个字典
    3. 混合使用参数的时候,可变参数要放在参数列表最后,普通参数放在参数列表前面,位置可变参数需要放在关键字参数之前
  • keyword-only参数(python3版本中加入)
    • 如果一个星号参数后,或者一个位置可变参数后,出现的普通参数,实际上已经不是普通参数了,而是keyword-only参数
    def fn(*args,x):
        print(x)
        print(args)
    
    测试调用fn(3,5)、fn(3,5,7)、fn(3,5,x=7)
    
    args可以看作已经截获了所有的位置参数,x不使用关键字参数就拿不到实参
    • 当一个可变关键字参数后面有普通参数时,因为可变关键字参数本省就会收集所有的关键字参数的,这样就失去了意义,所以会直接报语法错误
    • keyword-only参数的另一种形式
    def fn(*,x,y):
        print(x,y)
    
    测试调用发现
    *号之后,普通形参都变成了必须给出的keyword-only参数
  • 可变参数和参数默认值
    1. 参数列表参数规则:一般顺序是普通参数、缺省参数、可变位置参数、keyword-only参数(可带默认值)、可变关键字参数
    2. 注意
      • 代码应该易读易懂
      • 请按照哦书写习惯定义函数参数

参数解构

  • 参数解构
    1. 给函数提供参数的时候,可以在集合类型前使用或者*,把集合类型的结构解开,提取所有的元素作为函数的参数
    2. 非字典类型使用*解构成位置参数
    3. 字典类型使用**解构成关键字参数
    4. 提取出的元素数目要和参数的要求匹配,也要和参数的类型匹配
  • 参数解构和可变参数
    • 在给函数提供实参的时候,可以在集合类型前使用或者*,把集合类型的结构解开,提取出所有的元素作为函数的实参
    def add(*args):
        result = 0
        for x in args:
            result += x
        return result
        
    测试调用

练习

  • 编写一个函数,能够接受至少两个参数,返回最小值和最大值
    In [6]: def fn(*targ):
       ...:     return min(targ),max(targ)
    
    In [7]: fn(1,2,4,2,7)  #或者可以导入romdom模块,生成列表作为函数参数
    Out[7]: (1, 7)
  • 编写一个函数,接受一个参数n,n为正整数,打印出如下两种样式,要求数字需要对齐
1               
               2 1                  
             3 2 1      
           4 3 2 1      
         5 4 3 2 1      
       6 5 4 3 2 1      
     7 6 5 4 3 2 1  
   8 7 6 5 4 3 2 1  
 9 8 7 6 5 4 3 2 1  
 


 9 8 7 6 5 4 3 2 1
   8 7 6 5 4 3 2 1
     7 6 5 4 3 2 1
       6 5 4 3 2 1
         5 4 3 2 1
           4 3 2 1
             3 2 1
               2 1
                 1
def fn1(n):
    tail = ' '.join([str(i) for i in range(n,0,-1)])
    width = len(tail)
    for i in range(1,n):
        print('{:>{}}'.format(' '.join([str(j) for j in range(i,0,-1)]),width))
    print(tail)
----------------------------------------------------------
def f1(n):
    for i in range(1,n+1):
        print(' '.join([' '*(len(str(n)))]*(n-i)+[' '*(len(str(n))-len(str(j)))+str(j) for j in range(i,0,-1)]))
------------------------------------------------------------------------------
def fnl(n):
    for i in range(1,n+1):
        for j in range(n,0,-1):
            if i < j:
                print(' '*len(str(j)),end=' ')
            else:
                print(j,end=' ')
        print()
        
2. 

def fn2(n):
    tail = ' '.join([str(i) for i in range(n,0,-1)])
    print(tail)
    for i in range(len(tail)):
        if tail[i] == ' ':
            print(' '*i, tail[i+1:])
-------------------------------------------------
def fnl(n):
    for i in range(n,0,-1):
        for j in range(n,0,-1):
            if i < j:
                print(' '*len(str(j)),end=' ')
            else:
                print(j,end=' ')
        print()

上下合在一起

def fnl(n):
    for i in range(-n,n+1):
        if i<0:
            for j in range(n,0,-1):
                if -i < j:
                    print(' '*len(str(j)),end=' ')
                else:
                    print(j,end=' ')
            print()
        elif i == 0:
            pass
        else:
            for j in range(n,0,-1):
                if i < j:
                    print(' '*len(str(j)),end=' ')
                else:
                    print(j,end=' ')
            print()

函数返回值

  • 返回值总结
    1. Python函数使用return语句返回‘返回值’
    2. 所有函数都有返回值,如果没有return语句隐式调用return None
    3. return语句并不一定是函数的语句块的最后一条语句
    4. 一个函数可以存在多个return语句,但是只有一条可以被执行。如果没有一条return语句被执行到,就隐式调用return None
    5. 如果有必要可以显示调用return None,可以简写为return
    6. 如果函数执行了return语句,函数就会返回,当前被执行的return语句之后的其他语句就不会被执行了
    7. 作用:结束函数调用,返回值
    8. 函数不能同时返回多个值
      • return [1,2,5] 是指明返回一个列表,是一个列表对象
      • return 1,2,5 看似返回多个值,实际上是饮食的被python封装成了一个元组
  • 函数嵌套
    1. 在一个函数中定义了另外一个函数
    2. 函数有可见范围,这就是作用域的概念
    3. 内部函数不能被外部直接使用,会报nameerror

本文来自投稿,不代表Linux运维部落立场,如若转载,请注明出处:http://www.178linux.com/87819

(0)
KX_ilKX_il
上一篇 2017-10-15 22:15
下一篇 2017-10-16 09:41

相关推荐

  • 博客启动计划&我个人理解的Python优缺点

    很久没有写博客了,因为最近一直在使用Python。Python实在不是一门好的工作用语言(我的观点是所有的动态语言都不是好的工作用语言,不仅是Python),但是自己玩还是可以的。但,生活所迫,还是要继续用的呀(笑)。 所以呢,博客还是要写的,java还是最喜欢的,Python也是要学习的,当然其实更多是总结了。既然博客要启动了,这篇文字就权当测试吧,使用公…

    Linux干货 2015-03-13
  • 类的继承

    Edit 类的继承 基本概念 面向对象三要素之一,继承Inheritance 举例: 人类和猫类都继承自动物类 个体继承自父母,继承了父母的一部分特征,但也可以有自己的个性 在面向对象的世界中,以父类继承,就可以直接拥有父类的属性和方法,这样可以减少代码、多复用。子类可以定义自己的属性和方法 class Animal: def shout(self): pr…

    2017-11-15
  • Python内建函数

    内建函数 标识id() 返回对象的唯一标识,CPython返回内存地址 哈希hash() 返回一个对象的hash值 类型type() 返回对象的类型 类型转换 int()、float()、bin()、hex()、oct()、bool()、list()、tuple()、dict()、set()、complex()、bytes()、bytearray() 输入i…

    2018-04-08
  • 选择排序 以及 set、dict、习题练习

    习题练习 仅作参考

    2017-10-10
  • enumerate用法和转置矩阵求解、效率测试

    enumerate用法和转置矩阵求解、效率测试

    2018-04-08