我有一种问题与模块plistlib。它工作得很好,除了保存列表。它不会将撇号保存为特殊字符。它确实将&
保存为&
,这很好,但将撇号保存为'
(而不是'
),这就不好了。我有很多有很多文本的列表,当我改变一些东西时(用脚本批量改变),它给了我一个头痛的git diff
,因为每一个'
将成为'
。
如何强制plistlib保存所有特殊字符转义的plist(毕竟,只有5个字符)?
我自己来回答这个问题,因为我已经找到了答案。
问题是模块plistlib
中的功能_escape(text)
。它只转义&
, <
和>
,虽然Xcode与它的plist阅读器转义所有五个字符(&
, <
, >
, '
和"
),这就是为什么我认为这个模块也应该。这也是模块plistlib
的一个很好的补充,类似于函数escape()
中ElementTree的参数entities
。该参数是一个包含要替换的附加字符的字典。与plistlib's
函数类似的save_plist()
将是一个好主意,这样我们可以转义额外的字符。
我的解决方案是基于所谓的猴子补丁。基本上,我复制了整个函数_escape(text)
,只是添加了额外的转义('
和"
):
from plistlib import _controlCharPat
def patched_escape(text):
m = _controlCharPat.search(text)
if m is not None:
raise ValueError("strings can't contains control characters; "
"use bytes instead")
text = text.replace("rn", "n") # convert DOS line endings
text = text.replace("r", "n") # convert Mac line endings
text = text.replace("&", "&") # escape '&'
text = text.replace("<", "<") # escape '<'
text = text.replace(">", ">") # escape '>'
text = text.replace("'", "'") # escape '''
text = text.replace(""", """) # escape '"'
return text
现在在我的脚本中,我将plistlib's
函数_escape(text)
替换为我的:
plistlib._escape = patched_escape
现在plistlib
正确转义和保存列表。关于猴子打补丁的通常警告也适用于此。我没有其他调用者,只有这个脚本,所以这样做很好。