0

I have an externally defined module which has a number of methods in it. I can get all the methods as a list with dir() like print(dir[Descriptors]) and I get a list ['BalabanJ', 'BertzCT',...]. Now I want to apply all the methods on a list of values [x1, x2, ...]. If I directly use Descriptors.BalabanJ(x1) it works. However, I want to do them in a loop like

from rdkit.Chem import Descriptors
for i in dir[Descriptors]:
    for x in [x1,x2,x3]:
        print(Descriptors.i(x))

, it says that Descriptors does not have method i in it. How can I implement this?

1
  • There is a type difference in 'BalabanJ' and .BalabanJ(). The first one is string while the latter is a function Commented Mar 14, 2019 at 15:33

4 Answers 4

4

I think that getattr is this for which you are looking

from rdkit.Chem import Descriptors
for i in dir(Descriptors):
    if callable(i):
        for x in [x1,x2,x3]:
            print(getattr(Descriptors ,i)(x))
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks! Can you explain it a bit?
I think full explanation is in BlueSheepToken post. getattr function allows to get object attribute by name (string). It can be used on modules, objects etc.
2

I would recommend 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 Comment

This also will fail if signature of function needs 0 or more than 1 argument, or type of argument is invalid. So i remind about inspect.signature function.
1

You can retrieve them with getattr

for instance

class Bar:
    def __init__(self, foo):
        self.foo = foo

    def p(self):
        print(self.foo)

bar = Bar('hello word')
getattr(bar, 'p')()

Be aware that if there is no method i, it will raise a value error, but you can set a default method

getattr(bar, 'pr', lambda :print('no such method: pr'))()

You need to define your class and pass it as a parameter as I did for bar if it is a class method

from rdkit.Chem import Descriptors
for i in dir[Descriptors]:
    for x in [x1,x2,x3]:
        print(getattr(Descriptors, i)(x))

you can take a look at getattr() official documentation

2 Comments

More relevant here would be getattr(bar, 'p')()
@mad_ Why so? (I mean why not, but why this one is more relevant?) (I fixed it)
1

For this the RDKit has the 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])

Output:

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 Comment

Oh thanks! I was keeping the question answer on purpose :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.