[Biopython-dev] Module reorganization for upcoming Bio.PDB enhancements

Eric Talevich eric.talevich at gmail.com
Thu Jun 10 21:49:39 EDT 2010


On Thu, Jun 10, 2010 at 7:45 PM, João Rodrigues <anaryin at gmail.com> wrote:

> Hello all,
>
> I'm having some issues dealing with this :x
>
> I created a module Bio.Struct that has the following contents:
>
> __init__.py
> Protein.py
> WWW/
>
> The __init__.py file has a read() method that calls PDBParser and returns a
> Structure object. So far so good I think. Then I added a method to
> Bio.PDB.Structure more or less like this:
>
>     def as_protein(self):
>
>         from Bio.Struct.Protein import Protein
>         prot = Protein(self)
>         return prot
>
> so when you call it you get a new object. Protein is a class that inherits
> from Structure and that has the search_ss_bonds function.
>
> I can make the new object get all the methods from Structure AND from
> Protein, but when I try to execute search_ss_bonds, it fails because
> child_list, a Structure method, comes empty.. In fact, the whole SMCRA
> object comes empty..
>
> How do I effectively do the inheritance on the Protein class?
>
> from Bio.PDB.Structure import Structure
>
> class Protein(Structure):
>
>     def __init__(self, protein):
>
>         self = protein
>
> This is what I last tried and doesn't work.. I've tried Structure.__init__,
> and several other things but to no avail. I'm sure this is simple OOP but I
> really can't understand that well how to do it ...
>
> Care to give a hand to a friend in need? :)
>
> Thanks in advance! By the way, I assume that if I got no comments on
> anything else on the GSOC thread that I'm doing a perfect job :P Thanks for
> that too :D
>
> Best!
>
> João [...] Rodrigues
>

Hi João,

You have it mostly correct, but you need to call the parent class's
constructor, too.

Here's the constructor for Structure:

    def __init__(self, id):
        self.level="S"
        Entity.__init__(self, id)

And here it is for Entity:

    def __init__(self, id):
        self.id=id
        self.full_id=None
        self.parent=None
        self.child_list=[]
        self.child_dict={}
        # Dictionary that keeps addictional properties
        self.xtra={}

See the problem? Every subclass of Entity takes an "id" argument and sets
the other attributes separately.

In Bio.Phylo, I used another convention for converting an object of one type
to a sub-class of the original type, as you're doing here. Rather than
change the arguments to the constructor (which could have weird
side-effects), I added a class method in the target class:

@classmethod
def from_structure(cls, struct):
    # Instantiate a Protein with the structure's id
    # Assign the other attributes individually from struct


Then Structure.as_protein() becomes fairly simple. Alternatively, you could
skip implementing Protein.from_structure() and do the attribute reassignment
in as_protein(). Or, covering all the options, implement from_structure()
but not as_protein(), and let the user figure it out.

Do you think it would also be useful if as_protein() or from_structure()
dropped any non-protein molecules during the conversion, and raise an error
if nothing's left? Or would that cause more problems than it solves?

Best,
Eric



More information about the Biopython-dev mailing list