在Biopython的PDB模块中实现等价

时间:2012-05-29 15:25:32

标签: python biopython

背景

在Biopython的PDB模块中,PDB structures被解析为Structure个对象,这些对象将结构的组件存储在SMCRA结构中(结构/模型/链/残留/原子) )。此层次结构的每个级别由继承Entity容器类的对象表示。

等价

我的问题是,任何两个Entity对象都不能相等。

从同一文件构建的结构不相等:

>>> from Bio import PDB
>>> parser = PDB.PDBParser()
>>> struct1 = parser.get_structure("1hgg", "pdb1hgg.ent")
>>> struct2 = parser.get_structure("1hgg", "pdb1hgg.ent")
>>> struct1 == struct2
False

该结构中的残留物不相等:

>>> first_res1 = struct1.get_residues().next()
>>> first_res2 = struct2.get_residues().next()
>>> first_res1 == first_res2
False

等等。

如果我们要分别解析相同的PDB文件,结构中的任何Entity对象都不能相等。

解决方案

这个问题的明显解决方案是永远不要解析相同的PDB文件两次。然后,我们有对象身份,因此,等价。但是,这个答案对我来说似乎不完整。

每个Entity对象都可以返回带有get_full_id()的标识元组。这个方法从顶层对象中提取所有id;对于结构中的每个Entity,它应该是唯一的,如果在构造Structure对象时提供了正确的PDB id,则它在所有结构中都是唯一的。

我测试Entity等价的解决方案仅仅是比较这个完整的id。那就是:

def __eq__(self, other):
    return self.get_full_id() == other.get_full_id()

问题

此时,我问的是Entity等价的实现是否合理。

  • 是否存在误报(例如提供相同PDB ID的不同结构)?
  • 只要我们需要测试等效性,只需手动比较完整的id就更好了吗?
  • 是否有任何理由在__eq__模块中未PDB未实现?

1 个答案:

答案 0 :(得分:1)

不定义__eq__的一个常见原因是它使事情不可取(因此您不能将它们用作字典键或将它们放在集合中),除非您还定义了一致__hash__函数,您的对象是不可变的。

对于对象,默认情况下__hash__只使用ID,即使对于可变对象也是如此,因为ID永远不会改变。但是,如果您定义自定义__eq__,则无法按ID进行散列,或者您将遇到两个对象可以比较相同但具有不同散列的情况,这与散列应该如何工作的方式不一致。所以你必须定义一个自定义的__hash__函数(你可以这样做),但是如果你的对象是可变的,你也不能/不应该真的那个,所以你只会有一个不可用的物体。哪个可能适合你。

在python docs here中查看更多信息。

所以你可以使用自定义__eq__,只要你不需要你的对象可以清洗,或者它们是不可变的;否则事情变得更复杂。或者您可以单独留下__eq__并将其他ID命名为完整ID,以免破坏可靠性。

我不清楚PDB ID的含义(特别是,是否可能存在误报),从这个角度判断您的__eq__实施是否合理。