zoukankan      html  css  js  c++  java
  • global、nonlocal、迭代器

    函数在调用的时候才执行

    v1 = '张三'
    def func():
        v1 = '李四'
        def inner():
            print(v1)
        v1 = '王五'
        inner()
    
    
    func()  # 王五 函数调用才执行,inner没执行时候,v1被覆盖为王五, inner函数没有v1 ,在外部函数中找
    print(v1)  # 张三  在全局作用域找
    v1 = '老男人'
    func()  # 王五
    print(v1)  # 老男人
    
    可变参数的坑
    # 如果默认参数指向的是可变的数据类型,那么无论调用多少次这个默认参数, 只向的都是同一个
    def func(a, l1=[]):
        l1.append(a)
        return l1
    
    
    print(func(10,))  # [10]
    print(func(20, []))  # [20]  重新赋值, 和之前的不是同一个
    print(func(30, ))  # [10, 30]
    
    
    # 先执行, 在打印,结果是不同的,修改的是同一个id地址
    def func(a, l2=[]):
        l2.append(a)
        print(id(l2))
        return l2
    
    
    ret1 = func(10,) # 与ret3 是id是同一个, 先执行ret1和ret3才打印
    ret2 = func(20, []) # 重新赋值了
    ret3 = func(100, )
    print(ret1)  # [10, 100]
    print(ret2)  # [20]
    print(ret3)  # [10, 100]
    
    # 1、局部作用域和全局作用域都有相同的值,那么局部作用域的值在使用的时候,必须先赋值,否则会有歧义,会报错
    # 以下会报错 : local variable 'count' referenced before assignment
    # count = 1
    # def func():
    #     print(count)
    #     count = 2
    # func()
    
    
    # # 2、局部作用域能引用全局作用域的值,但不能改变,local variable 'count' referenced before assignment
    # count = 1
    # def func():
    #     count += 2
    # func()
    
    global
    # global
    # 1、在局部作用域声明一个全局变量。 必须先执行函数后,才能引用否则会报错
    def func():
        global name
        name = '太白金星'
    
    
    func()
    print(name) # 太白金星
    
    # 以下会报错 name 'age' is not defined   必须先执行函数后,才能引用否则会报错
    # def func2():
    #     global age
    #     name = '太白金星'
    #
    # print(age)
    # func2()
    
    
    # 2、修改一个全局变量 没有global此时会报错的
    count = 1
    def func():
        global count
        count += 1
        return count
    print(func())  # 2
    
    nonlocal
    • 1,不能更改全局变量

    • 2,在局部作用域中,对父级作用域(或者更外层作用域非全局作用域)的变量进行引用和修改,并且引用的哪层,从那层及以下此变量全部发生改变。

      #1. 不能够操作全局变量, 以下会报错。 # no binding for nonlocal 'count' found
      # count = 1
      # def func():
      #     nonlocal count
      #     count += 1
      # func()
      
      
      # 2. 局部作用域:内层函数对外层函数的局部变量进行修改。
      
      def wrapper():
          num = 1
          def inner():
              nonlocal num
              num += 1
          print(num)  # 1 函数调用的时候才会执行
          inner()
          print(num)  # 2
      wrapper()
      
      可迭代对象、迭代器
      # 判断是否是可迭代对象:内部含有__iter__ 方法
      # str dic  set tuple range 是可迭代对象(可迭代对象占用内存)
      print('__iter__' in dir('hello')) # True dir是列出所有的方法
      
      # 迭代器
      # 内部含有__iter__ 和__next__方法的对象都是迭代器
      # 优点:节省内存,惰性按需索取 next
      # 缺点:速度慢,不会重新开始
      
      with open('函数参数顺序.py', encoding='utf-8', mode='r') as f:
          print('__next__' in dir(f) and '__iter__' in dir(f))
      
      # 可迭代对象转化为迭代器
      l = [1, 2]
      obj = iter(l)
      print(obj)  # 注意: 返回的是<list_iterator object at 0x103f81160>
      print(next(obj))  # 1
      print(next(obj))  # 2 继续打印下一个值, 不会从头开始
      # print(next(obj))  # StopIteration 报错
      
      
      l1 = [1, 2, 3, 4, 5, 6]
      obj = iter(l1)
      
      for i in range(2):
          print(next(obj))  # 1 2
      
      for i in range(2):
          print(next(obj))  # 3 4
      
      
      # 可迭代对象:
      #     是一个私有的方法比较多,操作灵活(比如列表,字典的增删改查,字符串的常用操作方法等),比较直观,但是占用内存,而且不能直接通过循环迭代取值的这么一个数据集。
      #     应用:当你侧重于对于数据可以灵活处理,并且内存空间足够,将数据集设置为可迭代对象是明确的选择。
      #     迭代器:
      #     是一个非常节省内存,可以记录取值位置,可以直接通过循环+next方法取值,但是不直观,操作方法比较单一的数据集。
      #     应用:当你的数据量过大,大到足以撑爆你的内存或者你以节省内存为首选因素时,将数据集设置为迭代器是一个不错的选择。(可参考为什么python把文件句柄设置成迭代器)。
      
      
      # for 循环 内部也是先转化为迭代器, 在next()
      #  while模拟for的内部循环机制:
      l = [1, 2, 3, 4]
      # # 1 将可迭代对象转化成迭代器
      obj = iter(l)
      # # 2,利用while循环,next进行取值
      while 1:
          try:
              print(next(obj))
          except StopIteration:
              break
      
  • 相关阅读:
    用AVIFile函数制做AVI文件基本步骤
    RHEL5下源码安装Mysql
    RHEL 6.2/i686配置使用CentOS YUM源
    教你选择最稳定的 MySQL 版本
    RHEL 6.2/i686桌面版解决风扇狂转的问题 安装官方闭源ATI显卡驱动
    Ubuntu 11.10下解决JUK播放MP3乱码的方法
    Ubuntu 10.04下SVN+Apache安装、配置与使用
    Ubuntu 11.10安装(卸载)ATI闭源驱动导致黑屏进不了系统的解决办法
    ubuntu 11.10下创建eclipse桌面快捷方式
    Ubuntu 11.10与Windows双系统的硬盘安装方法
  • 原文地址:https://www.cnblogs.com/jnsn/p/12806967.html
Copyright © 2011-2022 走看看