aaa*_*210 4 python regex scope yield generator
我使用yield来创建一个生成器,该生成器返回使用正则表达式和re.sub()提取的字符串块.虽然我发现了一种有效的方法,但我对它为什么单向工作而不是另一种工作有点困惑,如下所示:
这不起作用(processchunk()没有分配给splitmsg中声明的块):
def splitmsg(msg):
chunk = None
def processchunk(match):
chunk = match.group(1)
return ""
while True:
chunk = None
msg = re.sub(reCHUNK,processchunk,msg,1)
if chunk:
yield chunk
else:
break
Run Code Online (Sandbox Code Playgroud)
这确实有效(注意唯一的区别是块现在是一个列表块):
def splitmsg(msg):
chunks = [ None, ]
def processchunk(match):
chunks[0] = match.group(1)
return ""
while True:
chunks[0] = None
msg = re.sub(reCHUNK,processchunk,msg,1)
if chunks[0]:
yield chunks[0]
else:
break
Run Code Online (Sandbox Code Playgroud)
我的问题基本上是为什么看起来chunk/chunk变量的范围似乎取决于它是一个普通变量还是一个列表?
在python中,如果读取变量,可以从周围的范围"拉出"变量.所以以下内容将起作用:
def foo():
spam = 'eggs'
def bar():
print spam
foo()
Run Code Online (Sandbox Code Playgroud)
因为变量'垃圾邮件'正在周围范围内查找,foo功能.
但是,您无法更改周围范围的值.您可以更改全局变量(如果global在函数中声明它们),但是您不能spam对上述函数中的变量执行此操作.
(Python 3对此进行更改,它会添加一个新关键字nonlocal.如果您定义spam为nonlocal内部,则bar可以为该变量分配一个新值bar.)
现在到你的清单.那里发生的是你根本没有改变变量chunks.在整个代码中,chunks指向一个列表,并且仅指向该列表.就python而言,chunks变量在processchunk函数内不会改变.
什么不会发生的事情是,你改变的内容列表.您可以自由地为其分配一个新值chunks[0],因为它不是变量chunks,而是chunks第一个索引所引用的列表.Python允许这样做,因为它不是变量赋值,而是列表操作.
所以,你的"解决方法"是正确的,如果有点模糊.如果你使用Python 3,你可以声明chunks为nonlocal内部processchunk,然后事情也可以在没有列表的情况下工作.