#python #python-3.x
#python #python-3.x
Вопрос:
У меня есть внешне определенный модуль, в котором есть несколько методов. Я могу получить все методы в виде списка с помощью dir(), например, print(dir[Descriptors])
и я получаю список ['BalabanJ', 'BertzCT',...]
. Теперь я хочу применить все методы к списку значений [x1, x2, …]. Если я использую напрямую Descriptors.BalabanJ(x1)
, это работает. Однако я хочу выполнять их в цикле, подобном
from rdkit.Chem import Descriptors
for i in dir[Descriptors]:
for x in [x1,x2,x3]:
print(Descriptors.i(x))
в нем говорится, что в дескрипторах нет метода i. Как я могу это реализовать?
Комментарии:
1. Существует разница в типах
'BalabanJ'
и.BalabanJ()
. Первый представляет собой строку, а второй — функцию
Ответ №1:
Я думаю, что getattr
это то, что вы ищете
from rdkit.Chem import Descriptors
for i in dir(Descriptors):
if callable(i):
for x in [x1,x2,x3]:
print(getattr(Descriptors ,i)(x))
Комментарии:
1. Спасибо! Не могли бы вы немного объяснить это?
2. Я думаю, что полное объяснение содержится в сообщении BlueSheepToken. функция getattr позволяет получить атрибут объекта по имени (строка). Его можно использовать в модулях, объектах и т.д.
Ответ №2:
Я бы рекомендовал inspect
:
from rdkit.Chem import Descriptors
import inspect
for i in inspect.getmembers(Descriptors, callable):
for x in [1, 2, 3]:
print(i[0], i[1](x)) # name of function of Descriptors module, result
Комментарии:
1. Это также приведет к сбою, если сигнатуре функции требуется 0 или более 1 аргумента, или тип аргумента недопустим. Итак, я напоминаю о
inspect.signature
функции.
Ответ №3:
Вы можете получить их с помощью getattr
например
class Bar:
def __init__(self, foo):
self.foo = foo
def p(self):
print(self.foo)
bar = Bar('hello word')
getattr(bar, 'p')()
Имейте в виду, что если их нет method
i
, это вызовет ошибку значения, но вы можете установить метод по умолчанию
getattr(bar, 'pr', lambda :print('no such method: pr'))()
Вам нужно определить свой класс и передать его в качестве параметра, как я сделал для bar, если это метод класса
from rdkit.Chem import Descriptors
for i in dir[Descriptors]:
for x in [x1,x2,x3]:
print(getattr(Descriptors, i)(x))
вы можете взглянуть на официальную документацию getattr()
Комментарии:
1. Здесь более уместно было бы
getattr(bar, 'p')()
2. @mad_ Почему так? (Я имею в виду, почему нет, но почему этот более актуален?) (Я это исправил)
Ответ №4:
Для этого в RDKit есть MolecularDescriptorCalculator
.
from rdkit import Chem
from rdkit.ML.Descriptors import MoleculeDescriptors
from rdkit.Chem import Descriptors
descriptors = [d[0] for d in Descriptors._descList]
smiles = ['CCN','CCNC', 'CCN(C)C']
for d in descriptors[:3]: # just the first three descriptors
print(d)
calc = MoleculeDescriptors.MolecularDescriptorCalculator([d])
for s in smiles:
c = calc.CalcDescriptors(Chem.MolFromSmiles(s))
print(s, c[0])
Вывод:
MaxEStateIndex
CCN 4.847222222222222
CCNC 2.9305555555555554
CCN(C)C 2.125
MinEStateIndex
CCN 0.75
CCNC 1.0694444444444444
CCN(C)C 1.1388888888888888
MaxAbsEStateIndex
CCN 4.847222222222222
CCNC 2.9305555555555554
CCN(C)C 2.125
Комментарии:
1. О, спасибо! Я специально сохранил ответ на вопрос 🙂