• python全栈-Day 10


    一、命名空间和作用域

    1、内置命名空间——对应Python解释器

    • Python解释器一启动就可以使用的名字存储在内置命名空间中,比如print、len、list、tuple、dict==
    • 内置的名字在启动解释器的时候被加载进内存里

    2、全局命名空间——对应 非函数的自定义代码

    • 放置了我们设置的所有变量名和函数名(所有名字)
    • 在程序从上到下被执行的过程中,一次加载进内存的

    3、局部命名空间——对应 自定义函数

    • 是函数内部定义的变量名和函数名
    • 当调用函数的时候才会产生这个名称空间,随着函数执行的结束,该命名空间被回收

    4、命名空间的其他内容

    • 在局部,可以使用 当前局部、全局、内置命名空间中的名字。局部命名空间根据函数个数可能有多个,其之间是隔离的,不能相互调用
    • 在全局,可以使用 全局、内置命名空间的名字,但是不能使用局部命名空间的名字
    • 在内置,不可以使用 局部、全部命名空间的名字
    • 以上符合 依赖倒置原则:上层模块应该依赖底层模块,底层模块不能依赖上层模块
    • 在正常情况下使用内置的名字,会使用内置的函数或变量;在全局定义了和内置命名空间中 同名的名字时,会使用全局的函数或变量
    • ——即,如果自己有就用自己的,如果自己没有就找底层的
      print(max([1,2,3]))
      
      def max():    #重新定义了max的函数
          print('in max func')
      
      max()    #in max func----函数内存地址(),指的是内存调用
      print(max())    #None
      print(max)  #<function max at 0x101eb48c8>----函数名的值其实是  函数的内存地址

    5、作用域

    • 全局作用域:作用在全局,内置和全局名字空间中的名字都属于全部作用域
    • 局部作用域:作用在局部,函数-局部名字空间中的名字属于局部作用域
    • 对于不可变数据类型,在局部可以查看全局作用域中的变量,但是不能直接修改,如果想要修改,需要在该函数中添加一个声明
    1. global:声明一个全局变量,作用域 是全局和局部的命名空间----不建议使用,不安全!!!建议使用形参、实参、返回值来修改
    2. nonlocal:声明一个上层局部变量,作用域是 最近一层的可找到对应名字的命名空间
    • a = 1
      def func():
          #a += 2    #报错
          a = 2
          print(a)    #重新定义了一个局部变量a = 2
      
      func()
      print(a)  #1,全局变量1没有改变
      
      a = 1
      def func():
          global a
          a = 2
          print(a)  #2
      
      func()
      print(a)  #2
    • 两个方法:globals、locals----用的比较少
      a = 1
      b = 2
      def func():
          x = 'aaa'
          y = 'bbb'
          print(locals())  #返回局部作用域中的所有名字及其值
          print(globals())  #返回全局的名字
      func()

    二、三元运算符???视频丢失

    1、适合用三元运算的场景:

    • 必须要有结果
    • 必须要有if和else
    • 只能是简单的情况

    2、三元运算的格式:  变量 = 条件返回True的结果 if 条件 else 条件返回False的结果

    def max(a,b):
        return a if a>b else b
    
    print(max(1,2)) 

    三、函数的嵌套和作用域链

    1、一个函数嵌套调用的示例

    def max(a,b):
        return a if a>b else b
    
    def the_max(x,y,z):
        return max(x,max(y,z))
    
    print(the_max(12,3,4))

    2、函数嵌套的定义:

    #一个错误的函数嵌套定义的流程
    def outer():
        def inner():
            print('inner')
    
    outer()  #调用outer函数,outer函数体只定义了inner,没有执行inner内部的函数体
    
    #一个正确的函数嵌套定义的流程
    def outer():
        a = 1
        def inner():
            print(a)
            print('inner')
        inner()
    
    outer()  #调用outer函数,outer函数体定义了inner,之后又执行了inner内部的函数体

    3、作用域链:在内部函数使用变量的时候,是从小局部->大局部->全局->内置名字的过程,一级一级往上找,找到最近的一个就使用

    def outer():
        a = 1
        def inner():
            a = 1
            def inner2():
                nonlocal a
                a = a + 1
                print(a,'inner2')
            inner2()
            print(a, 'inner')
        inner()
        print(a, 'outer')
    outer()  #调用outer函数,outer函数体定义了inner,之后又执行了inner内部的函数体
    
    '''返回结果:
    2 inner2
    2 inner
    1 outer'''
    
    
    def outer():
        a = 1
        def inner():
            #a = 1
            def inner2():
                nonlocal a
                a = a + 1
                print(a,'inner2')
            inner2()
            print(a, 'inner')
        inner()
        print(a, 'outer')
    outer()  #调用outer函数,outer函数体定义了inner,之后又执行了inner内部的函数体
    
    '''返回结果:
    2 inner2
    2 inner
    2 outer'''

    四、函数名的本质----名字

    • 函数名本质上是一个指向函数内存地址的变量名
    • 函数名可以赋值
      def func():
          print('func')
      
      func2 = func    #函数名可以赋值
      func2()
    • 函数名可以作为容器类型(list、tuple、dict)的元素
      def func():
          print('func')
      
      l = [func,func2]    #函数名可以作为容器类型(list、tuple、dict)的元素
      for i in l:
          i()
    • 函数名可以作为函数的参数和返回值
      def func():
          print('func')
      
      def wahaha(f):    #函数名可以作为函数的参数
          f()
          return f
      wahaha(func)
      f1 = wahaha(func)    #函数名可以作为函数的返回值
    • 以上,函数名属于一个第一类对象,符合以下3个条件的对象就是第一类对象
    1. 可在运行期内创建
    2. 可用作函数的参数和返回值
    3. 可存入变量的实体

    五、闭包

    1、闭包的定义:嵌套函数,且内部函数调用外部函数的变量,就是闭包

    def outer():
        a = 1
        def inner():
            print(a)
        print(inner.__closure__)    #(<cell at 0x101def648: int object at 0x1009e0980>,)
    outer()
    print(outer.__closure__)    #None,返回结果没有cell at...,证明该函数不是闭包

    2、常见的闭包应用形式

    #一般情况下,闭包函数的调用必须通过调用外部函数来实现,会重复创建和删除,减少运行时间消耗
    #使用闭包的好处在于,保护一个局部变量a不被回收,且可以随时可以通过inn的全部变量调用
    def outer():
        a = 1
        def inner():
            print(a)
        return inner
    inn = outer()
    inn()    #将闭包函数的函数名作为返回值,并在全局使用一个变量接收,此时可以在外部调用该函数 

    3、闭包的一个实际应用

    #import urllib    #导入urllib模块
    from urllib.request import urlopen
    
    def get_url():
        url = 'https://www.baidu.com/'
        def get():
            ret = urlopen(url).read()
            print(ret)
        return get
    
    get_gunc = get_url()
    get_gunc()
    
  • 相关阅读:
    DELLR720 独立显卡DVI转VGA问题
    淘宝开源项目之Tsar
    remmina rdp远程连接windows
    linux 下查看硬件信息(mac,IP地址,硬盘型号,序列号等)
    Ubuntu16.04下安装googlechrome flash 插件和安装网易云音乐
    Linux实现crontab每秒秒执行
    Supervisord
    es 加磁盘扩容
    通知神器——java调用钉钉群自定义机器人
    python 退出程序的方式
  • 原文地址:https://www.cnblogs.com/txbbkk/p/9403856.html
Copyright © 2020-2023  润新知