【发布时间】:2014-01-29 00:59:38
【问题描述】:
请考虑以下代码:
import re
def qcharToUnicode(s):
p = re.compile(r"QChar\((0x[a-fA-F0-9]*)\)")
return p.sub(lambda m: '"' + chr(int(m.group(1),16)) + '"', s)
def fixSurrogatePresence(s) :
'''Returns the input UTF-16 string with surrogate pairs replaced by the character they represent'''
# ideas from:
# http://www.unicode.org/faq/utf_bom.html#utf16-4
# http://stackoverflow.com/a/6928284/1503120
def joinSurrogates(match) :
SURROGATE_OFFSET = 0x10000 - ( 0xD800 << 10 ) - 0xDC00
return chr ( ( ord(match.group(1)) << 10 ) + ord(match.group(2)) + SURROGATE_OFFSET )
return re.sub ( '([\uD800-\uDBFF])([\uDC00-\uDFFF])', joinSurrogates, s )
现在我下面的问题可能反映了一种 C/C++ 思维方式(而不是“Pythonic”思维方式),但我还是很好奇:
我想知道编译的 RE 对象 p 在 qcharToUnicode 和 SURROGATE_OFFSET 在 joinSurrogates 的评估是否会在每次调用各自的函数时进行,或者只在定义点进行一次?我的意思是在 C/C++ 中可以将值声明为 static const 并且编译将 (IIUC) 使构造只发生一次,但在 Python 中我们没有任何此类声明。
这个问题在编译的 RE 对象的情况下更为相关,因为似乎构造这样一个对象的唯一原因是避免重复编译,正如Python RE HOWTO 所说:
您应该使用这些模块级函数,还是应该获取模式并自己调用它的方法?如果你是 在循环中访问正则表达式,预编译它将节省一些函数调用。
...如果在每次函数调用时都进行编译,这个目的就会失败。我不想将符号p(或SURROGATE_OFFSET)放在模块级别,因为我只想将其可见性限制为相关功能。
那么解释器是否会做一些类似启发式的操作来确定特定符号指向的值是恒定的(并且仅在特定函数中可见),因此不需要在下一个函数中重建?此外,这是由语言定义的还是依赖于实现的? (希望我没有要求太多!)
一个相关的问题是关于qcharToUnicode 中函数对象lambda m 的构造——它是否也像def 声明的其他命名函数对象一样只定义一次?
【问题讨论】:
-
如果整个
def块在循环中,即使由def定义的命名函数也可以定义多次。一般来说,Python 很少假设在程序过程中会发生什么变化或不会发生什么变化。代码在程序流程中在运行时遇到时执行。
标签: python