技术分享图片
人生三从境界:昨夜西风凋碧树,独上高楼,望尽天涯路。 衣带渐宽终不悔,为伊消得人憔悴。 众里寻他千百度,蓦然回首,那人却在灯火阑珊处。

Python_函数

函数内容回顾

  一、函数:对功能或者动作的封装 (function)

      定义:

      def 函数名(形参列表):

        函数体(return)

      调用:

        函数名(实参列表)

      形参:在函数声明的位置写的变量

        1、位置参数

        2、默认值参数

        3、动态传参

          1、*args 位置参数的动态参数,接受的是元组

          2、**kwargs 关键字的动态传参,接受的是字典

               *和**在形参中是聚合 在实参中是打散

      实参:在函数调用的时候给的值

        1、位置参数

        2、关键字参数

        3、混合参数

      传参:把实参传递给形参的过程

      返回值 :

           1、不写return 或者只写return 

           2、return 值 返回一个值

           3、return val1,val2, val3 ....返回多个值,元组类型

      名称空间:

          1、内置名称空间

            ---Python解释器的内置的东西

          2、全局名称空间

            ---全局变量,全局函数

          3、局部名称空间  

            ---局部变量、在函数内部

      作用域:

          1、全局作用域 (内置+全局)

          2、局部作用域 (局部)

 

      globals() 查看全部作用域中的内容

      locals()   查看当前作用域的内容

      global     把全局变量引入函数中

      nonlocal  在局部中的函数,引入离他最近的局部变量

      函数调用   、 函数嵌套

  二、闭包

     --def outer():

        a = 10 ## 常驻内存

        def inner():

          print(a) ## 在内部使用的外面的变量

        return inner ## 返回了内部函数的内存地址

      fn = outer()

      fn()

    ## 这种结构叫做闭包

      作用:1、可以保护我的变量

         2、可以让一个变量常驻内存 (相当于 全局变量)

    ## 判断是否为闭包

      fn.__closure__ ## 有返回的就是东西,返回的是None则不是闭包

    ## 闭包的作用:保护变量、常驻内存

  三、迭代器(iterator)

      回顾 : 可迭代对象 (str、list、dict、tuple、set、open()、range()), int 不能迭代,那么什么是可迭代对象?

          dir() 可以查看某数据类型中可以执行的方法       

              s = "alex"

              print(dir(s))#在字符串中发现了__iter__.没有__next__

              a = 123

              print(dir(a))#在int中没有__iter__,没有__next__

              总结:

                str、list、dict、tuple、set、open()、range()中都有__iter__ , int没有__iter__

                ## 在数据类型中可以认为有__iter__ 是可迭代的

                ## 所有包含了__iter__的东西都可以使用for 循环进行迭代

                ## 迭代器、在for 循环内部, 调用了__iter__(), 访问__iter__()可以得到迭代器

 1 lst = [1, 2, 3, 4, 5]
 2 it = lst._iter__() ##iterator 迭代器
 3 while 1:
 4          try:
 5               it.__next__()
 6          except:
 7               print("结束了")
 8 
 9 ##此代码等于 for in 执行                 

  四、概括总结

      函数名(第一类对象):

        1、函数名可以当做变量使用

        2、函数名可以作为集合类的函数

        3、函数名可以作为参数传递

        4、函数名可以作为返回值返回(闭包)

      __name__ 查看函数的名字

      __doc__    查看函数的注释

      闭包:

        内部函数对外部函数中的变量的调用

        用法:

        def outer():

          a = 10

          def inner():

            print(a)

          return inner

        好处:

          保护变量、常驻内存

      迭代器:

        dir() 查看数据可以执行的方法

        (iterable) : 在数据内部存在__iter__() 可以被迭代的内容

        (iterator) : 迭代器,存在__iter__(),__next__()

        还可以引入collections中的Iterable和Iterator

        from collections import Iterable

         isinstance(对象,类型) 可以判断xxx对象是否xxx类型

        特征:

          1、节省内存

          2、惰性机制(只有执行__next__才会取值)

          3、只能向前

          for 循环内部使用的是迭代器

 五、生成器(本质上是迭代器的一种)

      def func():

        print("123")

        yield "456"  // 有yield 就是 生成器

      f1 = func()

      ret = f1.__next__() // 执行遇到yield就是打印出来 123,465

      ret = f1.__next__() // 执行没遇到就会报错,StopIteration....

      //  send() 用法

      def func():

        print("123")

        a = yield "456"  // 有yield 就是 生成器

        print("147",a)    

       f1 = func()

      ret = f1.__next__()       // 第一个必须用__next__

      ret = f1.send("大哈")  // 给上一个yield 传递值     

      //  send() 和 __next__()区别

        ## send() 不可以用开头

        ## send() 可以给上一个yield 传递值,不能给最后一个yield传值

      // 生成器本质是迭代器   

       def func():

        print("123")

        a = yield "456"  // 有yield 就是 生成器

        print("147",a)    

      f1 = func()

      print("__iter__" in dir(f1))  // 判断是否存在iter,返回True则表示是生成器

       // 推导式

      lst = [] # 创建列表
      for i in range(1,17): # 循环1-16
        lst.append("python%s"%i) # 装数据
      print(lst) 

      --->>>列表推导式:

          lst  = ["python%s "%i ifor i in range(1,17)]

          语法:

            [结果 for _ in range() if 判断]

          练习:

            ## 获取1-100内能被3整除的数

            lst = [i for i in range(1,101) if i % 3 == 0]

            ## 100以内能被3整除的数的平方

            lst = [ i**2 for i in range(1,101) if i % 3 == 0]

            ## 寻找名字中带有两个e的人的名字          

            names = [['Toal','Billy','Jefferson','Andrew','Wesley','Steven','Joe'],
            ['Alice','Jill','Ana','Weniy','Jemifer','Shery','Eva']]

            lst = [name for first in names for name in first if name.count("e") >= 2]

            print(lst)

      --->>> 字典推导式:  

            dic = {"张无忌":"九阳神功","乔峰":"降龙十八掌","楚留香":"香"}

            d = {dic[k]:k for k in dic}

            print(d)     

            语法:

              {key:vale for 循环 if 判断}  

            练习:     

              lst1=['东北','陕西','山西','开封','杭州','广东','济南']
              lst2=['大推皮','油泼面','老陈','灌汤包','西制埋鱼','早茶','胶东一锅鲜']

              dic = {lst1[i]:lst2[i] for i in range(len(lst1))}

              print(dic)

      --->>> 集合推导式:

           lst = ['周杰伦','周星驰','周润发','周星驰','周笔畅','周星驰','周伯通','周星驰']

           s = {el for el in lst}

           语法:

             {key for if }

      --->>> 生成器表达式:

            gen = (i for i in range(10)) ## generator

            print(gen.__next__())

          ## 元组没有推导式i

          ## (结果 for if ) ## 这不是元组推导式,这拿到的是生成器

          ## 可以直接使用生成器表达式创建生成器

          ## 生成器表达式和列表推导式区别

          ## 列表推导式:一次性把所有的数据创建出来,容易产生内存浪费

          ## 生成器表达式: 记录一次代码,然后每次需要的时候去生成器中执行这个代码

          ## 特性:

              1、 节省内存

              2、 惰性机制

              3、 只能向前

           练习:(难点)

            1、def func():

                print(111)

                yield 222

              g = func() ## 生成器

              g1 = (i for i in g) ## 生成器

              g2 = (i for i in g1) ## 生成器

              print(list(g)) ## 才会开始真正的取数据 111, [222]

              print(list(g1))  ## []

              print(list(g2))  ## []

            2、def add(a, b):

                return a + b

              def test():

                for r_i in range(4):

                  yield r_i

              g = test()

              for n in [2, 10]:

                g = (add(n, i) for i in g)

              print(list(g))

            // 看最后一个数乘以循环次数加上g ,就是最后的结果

            // 生成器记录内存中的代码

 

posted @ 2019-09-07 18:49  山海郡  阅读(163)  评论(0编辑  收藏  举报