Python 函数相关知识

Python 函数相关知识

  1. 初识

    函数以功能为导向,一个函数为一个功能,随调随用。

    减少代码的重复性,增强代码的可读性 。

  2. 函数的结构以及调用

    • 结构:

      def mylen(s):
          pass
      	return x,y
      

      def:关键字,定义函数。

      mylen:函数名,与变量设置相同规则,方便体现该函数功能。

      s:传进函数的参数。

      函数体:缩进,函数中尽量不要出现print。

      return:

      • 功能一:遇到return,则结束该函数。
      • 功能二:传回返回值,给调用者。如返回多个元素,是以元组的形式返回。
    • 调用:

      调用时候通过“函数名():”的形式才执行函数里面的函数体。

  3. 函数的传参

    • 目的:让函数封装的这个功能可以随调用者的需求而实现相应的结果。

    • 参数可以分为:实参、形参

      • 实参:函数执行所传进去的实际参数。

        1. 位置参数:从左至右,一一对应,不可多不可少,顺序不可乱。

        2. 关键字参数(默认参数):参数需要一一对应,不可多不可少,但是顺序可以打乱,因为调用函数时候指定参数名和值的对应进行传递。

          ★★★注意:默认参数如果为可变数据类型,那么不管函数调用几次,始终都是使用同一个变量。
          def func(a,alist=[]):
              alist.append(a)
              return alist
          print(func(10))         # 第一次调用,将10追加到alist列表中
          print((func(20,[])))    # 第二次调用,因为第二个参数定义了一个新的列表,所以本次调用中使用的是另一个空列表追加进了20这个数字。
          print(func(100))        # 第三次调用,第二个参数没有传入,所以默认使用之前函数定义的关键字参数,这个列表里面已经有一个数字10,所以本次调用进行追加进一个数字100.
          >>>[10]
             [20]
             [10, 100]   
          
        3. 混合参数:即传递参数时候前几个使用位置参数,后面使用关键字参数这样的形式进行传递。位置参数必须在关键字参数的前面。

      • 形参:在函数端,接收调用者传递进来的参数(变量)。

        1. 位置参数:与实参角度的位置参数是一种,和实参的位置参数一一对应。
        2. 默认参数:经常用的参数,可以设定一个默认值。传参的时候可以省略,函数运行的时候即使用默认值。
        3. 万能参数: args、kwargs (*的魔性用法)
          • "args”,约定俗称:args。

          • 在函数定义时,“*”代表聚合。它将所有的位置参数聚合成一个元组,赋值给了args。

        • “kwargs”,约定俗称:kwargs。

        • 在函数定义时,“**”+变量名称(kwargs)。它将所有的关键字参数聚合成一个字典,赋值给了kwargs。

        • “*”号的魔性用法

            min,*list1,max=range(10)
          print(min,list1,max)
            >>>0 [1, 2, 3, 4, 5, 6, 7, 8] 9
          
      • 仅限关键字参数(了解):即只能是“关键字参数”。写在args和kwargs中间的关键字参数,这个参数在调用函数的时候必须要给它传递值。

      • 形参的最终顺序:因为存在万能参数的原因,能够接收参数个数不定,所以形参定义的顺序必须要将位置参数放第一位,后面跟*args。

      • 同理,排第三位是默认参数,后面跟kwargs。

      • 最终顺序:位置参数,*args,默认参数,仅限关键字参数,**kwargs**

  4. 星号(*)在函数中的用法:

    • 在形参角度:

      1个星号+args:将所有的位置参数聚合成一个元组。

      2个星号+kwargs:将所有的关键字参数聚合成一个字典。

      def mysum(*args,**kwargs):
          n=0
          for i in args:
              n+=i
          print(kwargs)
          return n
      print(mysum(4,556,1,2,12,6,7,7,453,99,name='Selina',age=18))
      >>>{'name': 'Selina', 'age': 18}
         1147
      
    • 在实参(调用)角度:

      1个星号+可迭代对象:将该对象打散传入函数。

      def func(*args):
          return args
      print(func(*'Internet'))
      >>>('I', 'n', 't', 'e', 'r', 'n', 'e', 't')
      

      2个星号+字典:将字典打散成关键字参数(name='Selina')形式传入函数。

      def func(*args,**kwargs):
          return args,kwargs
      print(func(**{'name':'Selina','height':168},**{'age':18}))
      >>>((), {'name': 'Selina', 'height': 168, 'age': 18})
      
  5. 名称空间:命名空间

    • 全局名称空间:里面的变量为全局变量。存放一个py文件(除去函数、类内部的)的变量,函数名与函数的内存地址的关系。

    • 局部名称空间:里面的变量为局部变量。存放函数内部的变量与值的应对关系。

    • 内置名称空间:为Python提供的内置函数(如:print()、len()、input()……)开辟的名称空间。

      img

    • 加载顺序:1.内置名称空间 ---> 2.全局名称空间 ---> 3.局部名称空间(执行函数的时候)

    • 取值顺序:就近原则(LEGB原则),单向不可逆。

      1.局部名称空间 ---> 2.全局名称空间 ---> 3.内置名称空间

      name='amwkvi'
      def func(*args,**kwargs):
          # name='Selina'			# 函数内部如果定义该变量,打印出来的结果将是Selina
          print(name)
      func()
      >>>amwkvi
      
    • 作用域:

      1. 全局作用域:内置名称空间、全局名称空间。
      2. 局部作用域:局部名称空间。
      局部作用域可以从全局作用域获取变量,换句话说,全局变量可以被函数内部引用,引用但不可修改(指不可变元素,可变元素是可以被修改的,比如列表)。反之,局部变量不可以在全局作用域中使用。
  6. 函数的嵌套(高阶函数)

    • 注意函数嵌套时候的运行顺序,函数定义之后需要调用才运行,嵌套函数也是如此。

      例子:

      def fun2():
          print(2)
          def fun3():
              print(6)
          print(4)
          fun3()
          print(8)
      print(3)
      fun2()
      print(5)
      >>>3
      2
      4
      6
      8
      5
      
  7. globals()方法和locals()方法

    • globals()方法:返回的是全局作用域(内置+全局)中的所有内容,返回值类型为字典。
    • locals():返回的是当前作用域中的所有内容,返回值类型为字典。
      a=23
      b='like'
      def func():
          name='Selina'
          age=18
          height=168
          print(locals())					# 打印输出当前作用域中的所有变量
      func()
      print('---------------------------')
      print(globals())					# 打印全局作用域中的所有变量
      >>>{'name': 'Selina', 'age': 18, 'height': 168}
      ---------------------------
      {'__name__': '__main__', '__doc__': '\n注释:本段代码用于研究globals()和locals()两个内置函数。\n', '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x00000289A90112C8>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:/Python/Practice/函数/函数Practice.py', '__cached__': None, 'a': 23, 'b': 'like', 'func': <function func at 0x00000289AAC34B88>}
      
  8. 关键字:nonlocal、global

    • global(全局的):

      1. 在局部作用域内可以声明一个全局变量。
        声明格式:global+空格+变量名
        def func():
            global name,age			# 在函数内部定义了两个全局变量
            name = 'amwkvi'			# 定义和赋值需要分两行写
            age = 18
        func()
        print(name,age)
        >>>amwkvi 18
        
      2. 在函数内部可利用global关键字对某个全局变量进行修改。
        name = 'amwkvi'
        def func():
            global name			    # 在函数内部使用global关键字将全局变量引入到函数内部
            name = name+' Walking'	# 这样就可以对全局变量进行修改
            return name
        print(name)					# 调用函数之前打印name变量的值
        func()
        print(name)					# 调用函数之后再次打印,确认在函数内部可对变量进行修改。
        >>>amwkvi
        amwkvi Walking
        
    • nonlocal(非局部的):

      1. 不能操作全局变量
      2. 函数嵌套情况下,内层函数对外层函数的局部变量进行修改。
        def func():
            name = 'amwkvi'
            def inner():
                nonlocal name       # 将func函数里面的name变量引入到inner函数中
                name += ' Mr.H'     # 现在可以对name变量进行修改,否则只能引用无法修改
            print(name)             # 调用inner函数之前打印name变量查看值
            inner()
            print(name)             # 调用inner函数之后查看name的值
        func()
        >>>amwkvi
        amwkvi Mr.H
        
  9. 函数名的应用:

    • 函数名指向的是函数的内存地址,函数名+() 就可以执行该函数。

    • 即函数名就是特殊的变量。

    • 类型:class 'function'

      def func():
          print('函数就是特殊的变量')
      f1 = func			# 将函数名赋值给一个变量。
      f2 = f1				# 再转一手。
      f2()				# 这个变量后面加(),可以直接执行这个函数。
      print(type(f1), type(f2))
      >>>函数就是特殊的变量
      <class 'function'> <class 'function'>
      
    • 函数名可以作为容器类数据类型的元素:

      def func1():				# 定义三个函数
          print('in func1')
      def func2():
          print('in func2')
      def func3():
          print('in func3')
      list1=[func1,func2,func3]   # 函数名可以当作容器类数据的元素。
      for l in list1:             # 可以被遍历。
          l()                     # 遍历出来的每个元素可以加()直接执行。
      
    • 函数名可以作为函数的参数:

      def func1():
          print('in func1')
      def func2(f):           # 位置参数f。
          f()                 # 接收到变量之后后面加了个()。
      func2(func1)            # 将函数名当作位置参数传入func2中。
      >>>in func1
      
    • 函数名可以作为函数的返回值:

      def func1():
          print('in func1')
      def func2(f):
          print('in func2')
          return f            # 返回值是函数名变量。
      res=func2(func1)        # 将函数名为作参数传入func2中。
      res()                   # 接收到返回值之后加()就可以直接执行该函数。
      >>>in func2
      in func1
      
  10. Python 匿名函数:lambda

    匿名函数:也叫一句话函数,一行构建一个函数,比较简单的函数。

    • 语法:函数名 = lambda 参数 : 返回值

    ​ 1.此函数不是没有名字,他是有名字的,他的名字就是你给其设置的变量,比如func。

    ​ 2.lambda 是定义匿名函数的关键字,相当于函数的def。

    ​ 3.lambda 后面直接加形参,形参加多少都可以,只要用逗号隔开就行。

    func = lambda a,b,*args,sex= 'alex',c,**kwargs: kwargs
    print(func(3, 4,c=666,name='alex'))  # {'name': 'alex'}
    # 所有类型的形参都可以加,但是一般使用匿名函数只是加位置参数,其他的用不到。
    

    ​ 4.返回值在冒号之后设置,返回值和正常的函数一样,可以是任意数据类型。

    ​ 5.匿名函数不管多复杂,只能写一行,且逻辑结束后直接返回数据。

    • 举例:

    def func(a, b):
        return a + b
    
    # 下面构建匿名函数
    func1 = lambda a, b: a + b      # lambda为关键字(相当于def),冒号前面为形参,冒号后面为返回值
    print(func1(3,4))				# 7
    
    # 写匿名函数:接收一个可切片的数据,返回索引为0与2的对应的元素(元组形式)。
    lam1 = lambda x: (x[0],x[2])
    print(lam1('amwkvi'))
    
    # 写匿名函数:接收两个int参数,将较大的数据返回。
    func1=lambda a,b: a if a>b else b
    print(func1(1,10))
    
posted @ 2020-12-10 16:03  amwkvi  阅读(71)  评论(0编辑  收藏  举报