PyMOL选取配体周边残基定点突变时遇报错的技术问询
问题背景
我在PyMOL中创建配体ECI 5埃范围内的残基选择集,计划对每个选中残基执行丙氨酸定点突变。脚本能正常生成目标选择集,但执行突变步骤时触发错误:“‘Atom’ has no attribute ‘get_id’”
报错详情
“Atom” has no attribute “get_id”
File "C:\Users\will\AppData\Local\Schrodinger\PyMOL2\lib\site-packages\pmg_qt\pymol_qt_gui.py", line 1192, in file_run
self.cmd.run(fname)
File "C:\Users\will\AppData\Local\Schrodinger\PyMOL2\lib\site-packages\pymol\parsing.py", line 470, in run
run_(path, ns_pymol, ns_pymol)
File "C:\Users\will\AppData\Local\Schrodinger\PyMOL2\lib\site-packages\pymol\parsing.py", line 519, in run_file
execfile(file,global_ns,local_ns)
File "C:\Users\will\AppData\Local\Schrodinger\PyMOL2\lib\site-packages\pymol\parsing.py", line 514, in execfile
exec(co, global_ns, local_ns)
File "C:/Users/will/PycharmProjects/Binding Residues/bindingresidue.py", line 10, in
res_id = residue.get_id()[1]
原脚本代码
from pymol import cmd cmd.load(r"C:\Users\will\.pymol\Acb1test.pdb", "Acb1") cmd.remove("not chain A and not residue ECI") cmd.select("eci_residue", "chain A and resn ECI") cmd.select("binding_residues", "(byres (eci_residue around 5))") protein = "Acb1" for residue in cmd.get_model("binding_residues").atom: res_id = residue.get_id()[1] res_name = residue.get_parent().get_resname() if res_name == "ALA": cmd.wizard("mutagenesis") cmd.wizard().set_mode("ser") cmd.get_wizard().do_select(f"chain A and residue{res_id}") cmd.get_wizard().apply() else: cmd.wizard("mutagenesis") cmd.get_wizard().set_mode("ala") cmd.get_wizard().do_select(f"chain A and residue{res_id}") cmd.get_wizard().apply() cmd.save(r"C:\Users\will\Acb1test\{protein}_{res_id}.pdb") cmd.reinitialize() cmd.load(r"C:\Users\will\.pymol\Acb1test.pdb", "Acb1") cmd.remove("not chain A and not residue ECI") cmd.select("binding_residues", "br. (byres (residue ECI around 5))") cmd.delete("binding_residues")
报错原因
- 遍历对象错误:
cmd.get_model("binding_residues").atom返回的是原子对象列表,而非残基对象。你将原子当作残基调用get_id()方法,但PyMOL的Atom类没有该方法,直接触发报错。 - 重复初始化效率低下:每次突变后执行
cmd.reinitialize()再重新加载蛋白,不仅耗时,还容易丢失中间状态。 - 选择语法错误:
residue{res_id}缺少空格,PyMOL无法正确识别残基选择规则,应该写成residue {res_id}。 - 字符串格式化错误:保存路径中的
{protein}_{res_id}未使用f-string语法(缺少f前缀),会导致文件名直接显示{protein}而非实际蛋白名称。
解决方法
- 正确获取残基列表:改用
cmd.get_model("binding_residues").residues遍历残基对象,残基对象可直接通过resi属性获取残基ID,通过resn属性获取残基名称,无需调用get_id()。 - 避免重复初始化:提前保存原始蛋白的副本,每次突变前恢复原始状态,替代重新加载的操作。
- 修正选择语法:将残基选择语句改为
f"chain A and residue {res_id}",确保空格正确。 - 修正文件名格式化:将保存路径改为f-string格式,确保变量能正确替换为实际值。
修正后的脚本
from pymol import cmd # 加载原始蛋白并预处理 cmd.load(r"C:\Users\will\.pymol\Acb1test.pdb", "Acb1") cmd.remove("not chain A and not residue ECI") cmd.select("eci_residue", "chain A and resn ECI") cmd.select("binding_residues", "(byres (eci_residue around 5))") protein = "Acb1" # 保存原始蛋白副本,避免每次重新加载 cmd.create("Acb1_original", "Acb1") # 获取绑定残基的残基列表(而非原子列表) residue_list = cmd.get_model("binding_residues").residues for res in residue_list: res_id = res.resi res_name = res.resn # 恢复原始蛋白状态 cmd.delete("Acb1") cmd.create("Acb1", "Acb1_original") # 执行定点突变 cmd.wizard("mutagenesis") if res_name == "ALA": cmd.get_wizard().set_mode("ser") else: cmd.get_wizard().set_mode("ala") cmd.get_wizard().do_select(f"chain A and residue {res_id}") cmd.get_wizard().apply() cmd.set_wizard() # 关闭突变向导 # 保存突变后的结构 save_path = fr"C:\Users\will\Acb1test\{protein}_{res_id}.pdb" cmd.save(save_path, "Acb1") # 清理临时对象 cmd.delete("Acb1_original") cmd.delete("binding_residues")
内容的提问来源于stack exchange,提问作者Shayan Joarder

