首页 > 解决方案 > 无法访问 rdkit 中 Chem.Atom 子类中的实例属性

问题描述

我定义了Atomin的一个子类rdkit.Chem。我还在其中定义了一个实例属性,但我无法从RWMolrdkit 中的对象获取该实例。

下面是我的问题的示例代码:

from rdkit import Chem

class MyAtom(Chem.Atom):

    def __init__(self, symbol, **kwargs):
        super().__init__(symbol, **kwargs)
        self.my_attribute = 0

    def get_my_attribute(self):
        return self.my_attribute

if __name__ == '__main__':
    rw_mol = Chem.RWMol()

    # I created MyAtom class object then added to RWMol. But I couldn't get it again.
    my_atom = MyAtom('C')
    my_atom.my_attribute = 3

    rw_mol.AddAtom(my_atom)
    atom_in_mol = rw_mol.GetAtoms()[0]

    # I can access my_atom new defined attributes.
    print(my_atom.get_my_attribute())

    # below two line gives error: AttributeError: 'Atom' object has no attribute 'get_my_attribute'
    print(atom_in_mol.get_my_attribute())
    print(atom_in_mol.my_attribute)

    # type(atom1): <class '__main__.MyAtom'>
    # type(atom_in_mol): <class 'rdkit.Chem.rdchem.Atom'>
    # Why below atom types are different? Thanks to polymorphism, that two object types must be same.

通常,此代码必须运行,但由于最后一行,它会给出错误,因为atom_in_mol objecttype 是Chem.Atom. 但它应该是MyAtom吗?我也无法my_attribute直接访问。

rdkit Python 库是 C++ 的包装器。那么问题是这个吗?我不能对这个库使用继承吗?

注意:我研究了 rdkit 文档,并且有一种SetProp将值保存在原子中的方法。它使用字典来保存值。它运行良好,但对我的项目来说太慢了。我想使用实例属性来保存我的额外值。有没有针对该继承问题的解决方案,或者更快的不同解决方案?

标签: python-3.xinheritancerdkit

解决方案


Python RDKit 库是一个 C++ 包装器,因此有时它不遵循传统的 Python 对象处理。

要更深入,您将不得不深入研究源代码:

rw_mol.AddAtom(my_atom)

上面将执行AddAtom方法 in rdkit/Code/GraphMol/Wrap/Mol.cpp,然后调用方法addAtomin rdkit/Code/GraphMol/RWMol.h,然后调用addAtom方法 in rdkit/Code/GraphMol/ROMol.cpp,默认参数为updateLabel = trueand takeOwnership = false

takeOwnership = false条件使参数原子被复制,

// rdkit/Code/GraphMol/ROMol.cpp
if (!takeOwnership)
  atom_p = atom_pin->copy();
else
  atom_p = atom_pin;

最后,如果您查看rdkit/Code/GraphMol/Atom.cppcopy中的哪些方法

Atom *Atom::copy() const {
  auto *res = new Atom(*this);
  return res;
}

因此,它重新实例化 Atom 类并返回它。


推荐阅读