Python 生成器注意事项

1.长列表适合写成生成器

读取文件中的内容,可以形成列表项。长的列表可能使内存崩溃。此时可以使用生成器。

def read_content(file):
	with open(file) as f:
		for line in f:
			yield line

2.生成器的状态

生成器作为一个迭代器,有状态,只能使用一次,第二次将返回空。

解决办法:

  • 短列表,可以用list复制内容
  • 使用lambda表达式,形成一个新列表
  • 使用类,复写__iter__()函数

    class Reader():

      def __init__(self, file):
          self.fileName = file
    
      def __iter__(self):
          with open(self.fileName) as f:
              for line in f:
                  yield line
    

3.变长参数中作用生成器(*arg)

变长参数,会首先转换为元组,所以如果是生成器,则会遍历所有元素,如果很多,则可能引起崩溃

4.参数数据收集器,变长参数(*arg,**argm)

*arg,收集所有除位置参数以外的参数

**argm,收集所有位置参数

调用过程中,参数加*与不加*的结果是不一样的。

def log(msg, *val, **kk):
    print(msg)
    print(val)
    print(kk)
    
if __name__=='__main__':
    list=["k",1,2]
    dict={"m":88,"n":99}
    log("tmp",11,22,list,dict,pp=66)
	log("tmp",11,22,*list,*dict,pp=66)
	log("tmp",11,22,*list,**dict,pp=66)

结果:
tmp
(11, 22, ['k', 1, 2], {'m': 88, 'n': 99})
{'pp': 66}

tmp
(11, 22, 'k', 1, 2, 'm', 'n')
{'pp': 66}

tmp
(11, 22, 'k', 1, 2)
{'m': 88, 'n': 99, 'pp': 66}

python 变量作用域

作用域而言,Python与C有着很大的区别,在Python中并不是所有的语句块中都会产生作用域。只有当变量在Module(模块)、Class(类)、def(函数)中定义的时候,才会有作用域的概念。

在作用域中定义的变量,一般只在作用域中有效。 需要注意的是:在if-elif-else、for-else、while、try-except\try-finally等关键字的语句块中并不会产成作用域.

使用global关键字来声明变量的作用域为全局.

搜索变量名的优先级:局部作用域 > 嵌套作用域 > 全局作用域 > 内置作用域

LEGB法则: 当在函数中使用未确定的变量名时,Python会按照优先级依次搜索4个作用域,以此来确定该变量名的意义。首先搜索局部作用域(L),之后是上一层嵌套结构中def或lambda函数的嵌套作用域(E),之后是全局作用域(G),最后是内置作用域(B)。按这个查找原则,在第一处找到的地方停止。如果没有找到,则会出发NameError错误。

参考:

  1. my coding.net
  2. https://www.cnblogs.com/fireporsche/p/7813961.html