Атрибуты экземпляра в подклассе Chem.Atom в rdkit недоступны - PullRequest
0 голосов
/ 15 января 2020

Я определил подкласс Atom в rdkit.Chem. Я также определил атрибут экземпляра в нем, но я не смог получить этот экземпляр из RWMol объекта в rdkit.

Ниже приведен пример кода для моей проблемы:

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 object равен Chem.Atom. Но должно ли это быть MyAtom? Я также не могу получить прямой доступ к my_attribute. Библиотека

rdkit Python является оболочкой C ++. Так проблема в этом? Не могу ли я использовать наследование для этой библиотеки?

Примечание: я исследовал документацию по rdkit и существует метод SetProp для сохранения значений в атомах. Он использует словарь для сохранения значений. Он работает нормально, но слишком медленно для моего проекта. Я хочу использовать атрибуты экземпляра, чтобы сохранить мои дополнительные значения. Есть ли какое-нибудь решение для этой проблемы наследования или более быстрое другое решение?

1 Ответ

1 голос
/ 18 января 2020

Python Библиотека RDKit - это оболочка C ++, поэтому иногда она не соответствует обычной обработке Python объектов.

На go глубже вам придется копаться в исходном коде:

rw_mol.AddAtom(my_atom)

Выше будет выполняться AddAtom метод в rdkit/Code/GraphMol/Wrap/Mol.cpp, который, в свою очередь, вызывает addAtom метод в rdkit/Code/GraphMol/RWMol.h, который затем вызывает addAtom метод в rdkit/Code/GraphMol/ROMol.cpp с аргументом по умолчанию updateLabel = true и takeOwnership = false.

Условие takeOwnership = false приводит к дублированию атома аргумента,

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

Наконец, если вы посмотрите, что метод copy делает в rdkit / Code / GraphMol / Atom. cpp

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

Итак, он восстанавливает класс Atom и возвращает его.

...