MacOS下使用plistlib修改Info.plist时出现追加而非覆盖问题
解决plistlib.dump()追加内容而非覆盖Info.plist的问题
嘿,这个坑我之前踩过!你遇到的问题本质是文件打开模式和文件指针位置不对,导致plistlib.dump()把新内容追加到了原文件末尾,而不是覆盖原有内容。
问题根源
当你用open()打开文件时:
- 如果用
'r+'或'r+b'模式,读取完文件内容后,文件指针会停在文件末尾,这时候直接调用dump()就会从末尾开始写入,变成追加。 - 如果不小心用了
'a'(追加模式),那不管怎样都会往后面加内容。
两种靠谱的解决方案
方案1:分两次打开文件(推荐,更直观)
先读取文件内容并修改,然后重新以写入模式打开文件(直接覆盖原内容):
import plistlib # 替换成你的.app包内Info.plist的实际路径 plist_path = "/Applications/YourApp.app/Contents/Info.plist" # 1. 读取原plist内容 with open(plist_path, 'rb') as fp: plist_data = plistlib.load(fp) # 2. 修改你需要的键值,比如修改应用显示名称 plist_data['CFBundleDisplayName'] = "我的自定义应用" # 或者修改版本号 plist_data['CFBundleShortVersionString'] = "1.5.0" # 3. 写入并覆盖原文件 with open(plist_path, 'wb') as fp: plistlib.dump(plist_data, fp)
这个方案的好处是逻辑清晰,'wb'模式会直接清空原文件再写入,完全避免追加问题,而且plistlib能自动处理XML或二进制格式的plist文件。
方案2:复用文件对象(需手动调整指针)
如果不想分两次打开文件,可以在写入前手动把文件指针移到开头,并截断文件:
import plistlib plist_path = "/Applications/YourApp.app/Contents/Info.plist" with open(plist_path, 'r+b') as fp: # 读取并修改内容 plist_data = plistlib.load(fp) plist_data['CFBundleVersion'] = "2.0.0" # 关键步骤:移到文件开头 + 截断后续内容 fp.seek(0) fp.truncate() # 写入修改后的内容 plistlib.dump(plist_data, fp)
这里'r+b'是读写二进制模式,seek(0)把指针移回文件开头,truncate()会删除指针之后的所有内容,这样dump()就会从开头覆盖原内容了。
额外注意事项
- 确保路径正确:.app是目录,Info.plist在
Contents子目录下,别写错路径! - 修改系统自带应用的Info.plist可能需要管理员权限,运行脚本时记得加
sudo。 - plistlib在Python 3.4+支持自动识别XML和二进制plist,不用手动指定格式。
内容的提问来源于stack exchange,提问作者Alice Isabelle
相关产品推荐
相关产品推荐

