zoukankan      html  css  js  c++  java
  • python学习之函数

    • 三元运算表达式
      • a = 1
      • b = 2
      • c = a if a > b else b # c 等于 如果a大于b得a,否咋等于b
    • 编程方式
      • 1、面向过程式编程:根据业务逻辑从上到下垒代码实现功能
      • 2、函数式编程:将某功能代码封装到函数中,日后使用相同功能时,无需重复编写,直接函数调用即可
      • 3、面向对象编程:对函数进行分类和封装,让开发“更快更好更强”
    • 函数式编程
      • 函数定义
        • 将可以实现某种功能,可重复使用的,组织在一起的代码块
      • 函数的作用
        • 增强代码的重用性和可读性
      • 函数语法
        • def 函数名 (参数可有可无)
          • 函数体(代码块)
          • return
      • 函数返回值 return
        • 函数执行完毕后,返回给调用者的结果(调用者需通过定义变量接受)
        • 函数一遇到return就结束,不再执行后面的代码,结束函数
          • 不写return ,python内置规定默认返回None
          • return None ,返回None
          • return 单个值 ,返回此单个值
          • return 多个值 ,将多个值包含在(元组)中,返回给调用者(可通过定义解构来直接接受)
      • 函数参数
        • 形参:函数定义时,声明的变量即括号里的变量
          • 位置参数
          • 默认参数
            • def fun(a,b,c ="默认值"):
            • 1、必须先声明位置参数,才能声明默认参数
          • 动态参数
            顺序:位置参数,*args,默认参数,**kwargs

            • 1、第一种:动态的位置参数
              • 语法:def fun(*args):pass
              • 传参:将多个参数以元组的形式传给函数
              • args 是元组,它包含了所有实参传过来的位置参数
            • 2、第二种:动态的关键字参数
              • 语法:def fun(**kwargs): pass
              • 传参:将多个参数以字典的形式传给函数,传参格式必须为“key”= “value”
              • kwargs 是字典,它包含了所有实参传过来的关键字参数
            • 3、第三种:无敌传参
              • 语法:def fun(*args,**kwargs):pass
              • *,**的作用:
                • 形参:聚合 (将元素聚合成元组,字典)
                • 实参:打散 (打散成各个元素,当变量传给函数)
        • 实参:调用者调用函数时实际给函数传的值
          • 位置参数
            • 实参与形参个数、位置必须一一对应
          • 关键字参数
          • 混合参数
            • 1、位置参数与关键字参数混合使用
            • 2、必须先写位置参数、后关键字参数,不然报错:(SyntaxError: positional argument follows keyword argument)
        • 作用域:
          • 在计算机执行自定义的函数时,计算机只会把函数名放在内存中,而函数体不会放在内存当中,因此在pycharm执行函数时,并不会真正的运算函数,函数内的语句题没有执行,只有遇见函数名()时才会在内存中圈定一块函数的运行区域,使函数开始执行
          • 全局命名空间
            • 直接在py文件中,函数外声明的变量都属于全局命名空间
          • 局部命名空间
            • 函数中声明的变量会放在局部命名空间
          • 内置命名空间
            • 存放python解释器提供的变量名称,list,tuple,str,int这些都是内置命名空间
          • 加载顺序:
            • 内置-全局-局部
          • 取值顺序
            • 局部-全局-内置
          • 作用域命名空间
            • 1、全局作用域:全局命名空间+内置命名空间(函数外面的)
            • 2、局部作用域:局部命名空间(函数里面的)
            • 查看方式:
              • 1、globals()函数查看全局作用域中的内容
              • 2、locals()函数查看局部作用域中的变量和函数信息
          • 改变变量的作用域
            • 1、global 变量 将函数局部作用域中的变量改成全局变量(也就是调用全局)
            • 2、nonlocal 变量 将当前局部作用域变量,改成上一级作用域中的变量(调用上级作用域)
              如果上一级没有该变量,继续找上一级,直到找到为止(非全局),否则返回空
          • 函数名
            第一类对象:可以在运行期调用、可用作函数参数或返回值,可存入变量的实体(当普通变量使)
            • 1、函数名的内存地址,print(func),它是函数整体的地址;id(func)是单纯func这个变量名的地址
            • 2、函数名可以赋值给其他变量 如:f = func
            • 3、函数名可以当做容器类的元素 如:【func1,func2】或【func1(),func2()】
            • 4、函数名可以当做函数的参数 如: def f(func)
            • 5、函数名可以当函数的返回值
          • 闭包
          • 在python中对闭包有特殊的机制,遇到闭包,它会在内存中开辟一个空间,不会随着函数的结束而结束,所以方便了多次的调用,减少多次对内存空间的关闭或打开,增加了代码块的执行效率。
            内层函数对外层函数(非全局)的变量的引用
            • 检测是不是闭包,函数名.__closure__ #cell
              通过nolocal引用的上一级局部变量,该函数也是闭包​​
            • 装饰器都是闭包函数
            • 语法范例
              • def func(f):
                • a = 0
                • def inner():
                  • print("此处调用外层函数的变量a或f,故inner函数为闭包函数",a)
                • return inner
          • 高阶函数
            • 两条件满足其一即可称为高阶函数
              • 1、函数名作为函数的返回值 return func_name
              • 2、函数名作为参数传入 func(fun_name)​
          • 装饰器(wrapper)
            • 定义:在不改变原函数的功能外(及调用方式),添加或扩展额外的功能
            • 开闭原则:对代码的扩展是开放的,对代码的修改是封闭的
            • 语法范例:(手写装饰器)
              • def wrapper_name (func):
                • def inner(*args,**kwargs):
                  • """计划在执行功能函数前扩展的功能"""
                  • ret = func(*args,**kwargs)
                  • """计划在执行功能函数后扩展的功能"""
                  • return ret
                • return inner
            • 装饰器调用:
              • func = wrapper_name(func)
              • func()
            • 语法糖调用:
              • 在需要扩展新功能的功能函数上方@装饰器函数名
              • @wrapper

         

           

    • 带参数的装饰器
      • 1、为了自定义是否使用扩展功能,更智能化,可以为是否使用扩展功能加个开关
      • 2、具体就是在装饰器函数外面再嵌套一层函数wrapper_out(flag),设定一个形参flag,返回值为装饰器函数名wrapper
      • 3、在inner函数里加一层判断flag为True使用附加功能,False为不添加附加功能
      • 3、在功能函数上加上@wrapper_out(True或者Falsh)
        •  1 # 带参数的装饰器
           2 # # 自定义是否使用添加的功能,故需要定义一个开关来是否执行通过装饰器添加的功能
           3 # # 1、如果在wrapper函数里添加的参数,就改变了调用装饰器的方式,因为调用装饰器时并没有给与参数:@wrapper
           4 # # 2、如果在inner函数里再添加参数,而inner函数里所有的参数都会给原功能函数,就会导致原功能函数执行异常
           5 """ 3、****故只能在wrapper函数外层再添加一层函数,加一个参数作为开关,来决定是否使用扩展功能,这就是装饰器添加参数***"""
           6 def wrapper_choice(flag):   # falg 是定义是否使用扩展功能的开关参数
           7     def wrapper(func_name):
           8         def inner(*args, **kwargs):
           9             if flag == True:    # 就使用扩展的功能
          10                 '''函数执行前添加的功能代码块'''
          11                 ret = func_name(*args, **kwargs)
          12                 '''函数执行后添加的功能代码块'''
          13                 return ret  # 返回执行结果
          14             else:  # 直接执行原函数,不要扩展功能
          15                 ret = func_name(*args, **kwargs)
          16                 return ret
          17         return inner  # 返回带有新功能且可以执行原函数的函数名
          18     return wrapper   # 返回装饰器函数名
          19 
          20 @wrapper_tell_you(True)  # 先执行右边的wrapper_tell_you(True)返回wrapper装饰器函数名,从而形成@wrapper
          21 def fun2(*args, **kwargs):
          22     pass
          23 fun2()  # 调用,相当于inner()调用
          带参数的装饰器

           

    • 装饰器的嵌套
      • 功能函数嵌套多层装饰器,记住取值顺序就不怕嵌套多少了
      • 装饰器中函数前添加的功能,函数后添加的功能可以用作括号来表示,中间是被装饰函数
        • 【 ( 被装饰函数 ) 】
        • 从左至右取值
        •  1 # 多个装饰器嵌套
           2 '''取值顺序:[   (    目标   )   ] 从左到右显示,
           3 最外层装饰器函数执行前功能、
           4 内层装饰器函数执行前功能
           5 原功能函数
           6 内层装饰器函数执行后功能
           7 最外层装饰器函数执行后功能'''
           8 def wrapper1(func1_name):
           9     def inner(*args, **kwargs):
          10         print("上车")
          11         ret = func1_name(*args,**kwargs)
          12         print("下车")
          13         return ret
          14     return inner
          15 
          16 def wrapper2(func2_name):
          17     def inner(*args, **kwargs):
          18         print("出发了……")
          19         ret = func2_name(*args, **kwargs)
          20         print("到站了……")
          21         return ret
          22     return inner
          23 
          24 def wrapper3(fun3_name):
          25     def inner(*args, **kwargs):
          26         print("计划去东莞了……")
          27         ret = fun3_name(*args, **kwargs)
          28         print("不虚此行,质量不错……")
          29         return ret
          30     return inner
          31 
          32 @wrapper3
          33 @wrapper2
          34 @wrapper1
          35 def by_car():
          36     print("去浪了……")
          37     return
          38 
          39 by_car()
          40 '''
          41 结果为:
          42 计划去东莞了……
          43 出发了……
          44 上车
          45 去浪了……
          46 下车
          47 到站了……
          48 不虚此行,质量不错……
          49 '''
          装饰器的嵌套取值顺序
    • 函数的注释:
      • 在函数体第一行用三个双引号将需要注释的内容写在里面,包括函数是干嘛的、函数的参数、函数的返回值
      • 语法:
        • def func_name(args):
          • """函数的注释内容"""
          • pass
      • 函数注释的查看:print(func_name.__doc__)
    • 函数名的查看:(因如果函数被装饰过,就不是它本来的名字了,而是装饰器返回来的inner)
      • 1、未被装饰过的函数名查看方法:print(func_name.__name__)
      • 2、被装饰过的函数需先导入模块、再在装饰器inner函数上面加一个装饰器@wrap(func_name)
      • 2.3、通过print(fn.__name__) 查看到的就不是inner而是本身的fn函数名了
      •  1 # 函数名的显示
         2 '''
         3 1、未加装饰器函数的函数名查看
         4 print(func_name.__name__)
         5 2、加了装饰器的函数,因为看起来还是原来的函数名,实际是返回来的inner函数名,
         6    故python做了一个优化,加了个功能,将函数名转换回来
         7 2.1、导入模块 from functools import wraps
         8 2.2、在inner函数上方加一个固定装饰器 @wraps(func_name)
         9 '''
        10 from functools import wraps
        11 def wrapper(fn):
        12     @wraps(fn)   # 这个代码的作用,将inner的__name__替换成fn的__name__
        13     def inner(*args, **kwargs):
        14         print("功能1")
        15         ret = fn(*args, **kwargs)
        16         return ret
        17     return inner
        18 @wrapper
        19 # 原功能函数
        20 def fun2(*args, **kwargs):
        21     pass
        22 print(fun2.__name__)  # fun2
        函数名的查看
    • 迭代器
        • 迭代器协议:必须为可迭代对象提供一个next方法,执行该方法要么返回迭代的下一项,要么就引起一个stopIteration的异常,终止迭代(只能往前走,不能回退)
        • 可迭代对象iterable:内部含有__iter__方法的对象、遵循可迭代协议、str、list、tuple、dict、set、range(int、float不是)
          • 判断是否为可迭代对象:print("__inter__" in dir(对象)) 或 from collections import Iterable;print(isinstance(对象,Iterable))
        • 迭代器iterator:内部含有__iter__和__next__方法的对象、遵循迭代器协议
          • 判断是否为迭代器:print("__iter__" and "__next__" in dir("djsks".__iter__())) 或 from collections import Iterator;print(isinstance(对象,Iterable))
        • 可迭代对象转成迭代器:对象.__iter__()
        • 迭代器的好处:节省内存、满足惰性机制(运行一次在内存中取一次值)、不能反复取值,只能从前到后,下一次接着上一次后面取,不可逆
        • 有哪些用了迭代器:for、sum、max、min等
        • for循环函数就是迭代器最好的例子
          • 1、通过__iter__()方法将可迭代对象转换成迭代器【对象.__iter__()】
          • 2、通过__next__()方法进行取值【对象.__next__()】
          • 3、通过异常处理机制规避报错
        • -----------------------下例以while模拟-------------------------------
        • lis = [11,33,44,55,66]
        • while True:
          • try:
            • gn = lis.__iter__()
            • print(gn)
          • except Exception:
            • break
        • -------------------------end--------------------------------------------
    •   生成器
        • (一般是函数)内部带有关键字yield的对象,生成器的本质是迭代器,遵循迭代器协议(所有的生成器一定是迭代器,反之不一定)
        • 函数中如有yield就不是普通的函数而是生成器,yield功能类似如return,为调用者返回函数执行结果,但yield后还有编码,不结束,而return是直接结束函数
        • --------------------示例------------------------
        • def func():
          • print("你想吃啥")
          • a = yield 2222
          • print(222)
          • yield 3333 # 出现yield就是生成器
        • gn = func() # gn就是迭代器
        • print(gn.__next__()) # 生成器调用元素,到第一个yield结束,等待第二次继续调用
        • print(gn.__send("红烧鲤鱼")
        • -----------------------------------------------------
        • send()和next()执行方法一样,都是返回一个迭代器内部的元素,使光标向后移动一个位置,但send可以上上一个yield传递一个参数,默认传none,改变上一个yield的值;第一次调用不能用send的因为第一个前面没有yield;最后一个元素不能改变其值
  • 相关阅读:
    现代JVM内存管理方法的发展历程,GC的实现及相关设计概述(转)
    jvm对大对象分配内存的特殊处理(转)
    用java字节码解释i++和++i(转)
    Git 常用命令手记 及 Github协同流程(转)
    经常使用git命令集
    Android手机分辨率基础知识(DPI,DIP计算)
    软件測试自学指南---从入门到精通
    惊!从一场离奇的命案说起
    java设计模式演示样例
    浅谈UML的概念和模型之UML九种图
  • 原文地址:https://www.cnblogs.com/sunxiuwen/p/9166840.html
Copyright © 2011-2022 走看看