zoukankan      html  css  js  c++  java
  • 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__': '
        注释:本段代码用于研究globals()和locals()两个内置函数。
        ', '__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))
      
  • 相关阅读:
    BZOJ 1578: [Usaco2009 Feb]Stock Market 股票市场( 背包dp )
    BZOJ 3315: [Usaco2013 Nov]Pogo-Cow( dp )
    BZOJ 3477: [Usaco2014 Mar]Sabotage( 二分答案 )
    BZOJ 2427: [HAOI2010]软件安装( dp )
    BZOJ 3211: 花神游历各国( 线段树 )
    POJ 2528 线段树 + 离散化
    POJ 1151 Atlantis 线段树+离散化+扫描线
    POJ1177 Picture 线段树+离散化+扫描线
    BZOJ1016: [JSOI2008]最小生成树计数
    POJ2104 K-th Number 划分树 模板题啊
  • 原文地址:https://www.cnblogs.com/amwkvi/p/14115590.html
Copyright © 2011-2022 走看看