Thi*_*ter 77 python closures scope python-2.x
我在函数中有以下代码:
stored_blocks = {}
def replace_blocks(m):
block = m.group(0)
block_hash = sha1(block)
stored_blocks[block_hash] = block
return '{{{%s}}}' % block_hash
num_converted = 0
def convert_variables(m):
name = m.group(1)
num_converted += 1
return '<%%= %s %%>' % name
fixed = MATCH_DECLARE_NEW.sub('', template)
fixed = MATCH_PYTHON_BLOCK.sub(replace_blocks, fixed)
fixed = MATCH_FORMAT.sub(convert_variables, fixed)
Run Code Online (Sandbox Code Playgroud)
添加元素stored_blocks
工作正常,但我不能增加num_converted
第二个子功能:
UnboundLocalError:赋值前引用的局部变量'num_converted'
我可以使用,global
但全局变量是丑陋的,我真的不需要该变量是全局的.
所以我很好奇如何写入父函数范围内的变量.
nonlocal num_converted
可能会完成这项工作,但我需要一个适用于Python 2.x的解决方案.
Mar*_*tos 86
问题:这是因为Python的范围规则是疯狂的.+=
赋值运算符的存在将目标标记num_converted
为封闭函数范围的本地,并且Python 2.x中没有声音方法可以从那里访问一个范围级别.只有global
关键字可以将变量引用提升到当前范围之外,它会直接将您带到顶部.
修正:转num_converted
成一个单一的元素数组.
num_converted = [0]
def convert_variables(m):
name = m.group(1)
num_converted[0] += 1
return '<%%= %s %%>' % name
Run Code Online (Sandbox Code Playgroud)
Pab*_*loG 29
(见下面的编辑答案)
您可以使用以下内容:
def convert_variables(m):
name = m.group(1)
convert_variables.num_converted += 1
return '<%%= %s %%>' % name
convert_variables.num_converted = 0
Run Code Online (Sandbox Code Playgroud)
这样,num_converted
作为convert_variable方法的类似C的"静态"变量
(编辑)的
def convert_variables(m):
name = m.group(1)
convert_variables.num_converted = convert_variables.__dict__.get("num_converted", 0) + 1
return '<%%= %s %%>' % name
Run Code Online (Sandbox Code Playgroud)
这样,您无需在主过程中初始化计数器.
使用global
关键字很好.如果你写:
num_converted = 0
def convert_variables(m):
global num_converted
name = m.group(1)
num_converted += 1
return '<%%= %s %%>' % name
Run Code Online (Sandbox Code Playgroud)
... num_converted
不会成为"全局变量"(即它在任何其他意想不到的地方都不可见),它只是意味着它可以在里面修改convert_variables
.这似乎正是你想要的.
换句话说,num_converted
它已经是一个全局变量.所有global num_converted
语法都告诉Python"在这个函数内部,不要创建局部num_converted
变量,而是使用现有的全局变量.
使用类实例来保存状态怎么样?您实例化一个类并将实例方法传递给subs,这些函数将引用self ...
我有几个评论.
首先,在处理原始回调时会出现一个这样的嵌套函数的应用程序,就像xml.parsers.expat这样的库中使用的那样.(图书馆作者选择这种方法可能令人反感,但......仍然有理由使用它.)
第二:在一个类中,有更好的替代数组(num_converted [0]).我想这就是Sebastjan所说的.
class MainClass:
_num_converted = 0
def outer_method( self ):
def convert_variables(m):
name = m.group(1)
self._num_converted += 1
return '<%%= %s %%>' % name
Run Code Online (Sandbox Code Playgroud)
在代码中值得评论仍然很奇怪......但变量至少是本地的本地变量.
归档时间: |
|
查看次数: |
24617 次 |
最近记录: |