Документ взят из кэша поисковой машины. Адрес оригинального документа : http://kodomo.fbb.msu.ru/hg/allpy/raw-rev/e3bcb9f8d7b0
Дата изменения: Unknown
Дата индексирования: Tue Oct 2 07:28:26 2012
Кодировка:

# HG changeset patch
# User Daniil Alexeyevsky
# Date 1292592538 -10800
# Node ID e3bcb9f8d7b0764ae203eb320697911b9fdb0895
# Parent 0435d9cc18d3c04d7585dac6d00e9085da4f00c1
Got rid of all MonomerType classes

diff -r 0435d9cc18d3 -r e3bcb9f8d7b0 allpy/base.py
--- a/allpy/base.py Fri Dec 17 00:58:54 2010 +0300
+++ b/allpy/base.py Fri Dec 17 16:28:58 2010 +0300
@@ -7,140 +7,71 @@
default_gaps = set((".", "-", "~"))
"""Set of characters to recoginze as gaps when parsing alignment."""

-class MonomerType(object):
- """Class of monomer types.
+class Monomer(object):
+ """Monomer object."""

- Each MonomerType object represents a known monomer type, e.g. Valine,
- and is referenced to by each instance of monomer in a given sequence.
-
- - `name`: full name of monomer type
- - `code1`: one-letter code
- - `code3`: three-letter code
- - `is_modified`: either of True or False
-
- class atributes:
-
- - `by_code1`: a mapping from one-letter code to MonomerType object
- - `by_code3`: a mapping from three-letter code to MonomerType object
- - `by_name`: a mapping from monomer name to MonomerType object
- - `instance_type`: class of Monomer objects to use when creating new
- objects; this must be redefined in descendent classes
-
- All of the class attributes MUST be redefined when subclassing.
- """
+ type = None
+ """Either of 'dna', 'rna', 'protein'."""

by_code1 = {}
+ """A mapping from 1-letter code to Monomer subclass."""
+
by_code3 = {}
+ """A mapping from 3-letter code to Monomer subclass."""
+
by_name = {}
- instance_type = None
-
- def __init__(self, name="", code1="", code3="", is_modified=False):
- super(MonomerType, self).__init__()
- self.name = name.capitalize()
- self.code1 = code1.upper()
- self.code3 = code3.upper()
- self.is_modified = bool(is_modified)
- if not is_modified:
- self.by_code1[self.code1] = self
- self.by_code3[code3] = self
- self.by_name[name] = self
- # We duplicate distinguished long names into MonomerType itself,
- # so that we can use MonomerType.from_code3 to create the relevant
- # type of monomer.
- MonomerType.by_code3[code3] = self
- MonomerType.by_name[name] = self
+ """A mapping from full monomer name to Monomer subclass."""

@classmethod
- def _initialize(cls, type_letter, codes=data.codes.codes):
- """Create all relevant instances of MonomerType.
+ def _subclass(cls, name='', code1='', code3='', is_modified=False):
+ """Create new subclass of Monomer for given monomer type."""
+ class TheMonomer(cls):
+ pass
+ name = name.strip().capitalize()
+ code1 = code1.upper()
+ code3 = code3.upper()
+ TheMonomer.__name__ = "Monomer"
+ TheMonomer.name = name
+ TheMonomer.code1 = code1
+ TheMonomer.code3 = code3
+ TheMonomer.is_modified = is_modified
+ if not is_modified:
+ cls.by_code1[code1] = TheMonomer
+ cls.by_code3[code3] = TheMonomer
+ cls.by_name[name] = TheMonomer
+ # We duplicate distinguished long names into Monomer itself, so that we
+ # can use Monomer.from_code3 to create the relevant type of monomer.
+ Monomer.by_code3[code3] = TheMonomer
+ Monomer.by_name[name] = TheMonomer

- `type_letter` is either of:
-
- - 'p' for protein
- - 'd' for DNA
- - 'r' for RNA
-
- `codes` is a table of monomer codes
- """
+ @classmethod
+ def _initialize(cls, codes=data.codes.codes):
+ """Create all relevant subclasses of Monomer."""
+ # NB. The table uses letters d, r, p for types,
+ # while we use full words; hence, we compare by first letter
for type, code1, is_modified, code3, name in codes:
- if type == type_letter:
- cls(name, code1, code3, is_modified)
+ if type[0] == cls.type[0]:
+ cls._subclass(name, code1, code3, is_modified)

@classmethod
def from_code1(cls, code1):
- """Return monomer type by one-letter code."""
- return cls.by_code1[code1.upper()]
+ """Create new monomer from 1-letter code."""
+ return cls.by_code1[code1.upper()]()

@classmethod
def from_code3(cls, code3):
- """Return monomer type by three-letter code."""
- return cls.by_code3[code3.upper()]
+ """Create new monomer from 3-letter code."""
+ return cls.by_code3[code3.upper()]()

@classmethod
def from_name(cls, name):
- """Return monomer type by name."""
- return cls.by_name[name.capitalize()]
-
- def instance(self):
- """Create a new monomer of given type."""
- return self.instance_type(self)
+ """Create new monomer from full name."""
+ return cls.by_name[name.strip().capitalize()]()

def __eq__(self, other):
- if hasattr(other, "type"):
- return self is other.type
- return self is other
-
-class Monomer(object):
- """Monomer object.
-
- attributes:
-
- - `type`: type of monomer (a MonomerType object)
-
- class attributes:
-
- - `monomer_type`: either MonomerType or one of it's subclasses, it is used
- when creating new monomers. It SHOULD be redefined when subclassing
- Monomer.
- """
- monomer_type = MonomerType
-
- def __init__(self, type):
- super(Monomer, self).__init__()
- self.type = type
-
- @classmethod
- def from_code1(cls, code1):
- return cls(cls.monomer_type.by_code1[code1.upper()])
-
- @classmethod
- def from_code3(cls, code3):
- return cls(cls.monomer_type.by_code3[code3.upper()])
-
- @classmethod
- def from_name(cls, name):
- return cls(cls.monomer_type.by_name[name.capitalize()])
-
- @property
- def code1(self):
- return self.type.code1
-
- @property
- def code3(self):
- return self.type.code3
-
- @property
- def name(self):
- return self.type.name
-
- @property
- def is_modified(self):
- return self.type.is_modified
-
- def __eq__(self, other):
- if hasattr(other, "type"):
- return self.type is other.type
- return self.type is other
+ """Monomers within same monomer type are compared by code1."""
+ assert self.type == other.type
+ return self.code1 == other.code1

class Sequence(list):
"""Sequence of Monomers.
diff -r 0435d9cc18d3 -r e3bcb9f8d7b0 allpy/dna.py
--- a/allpy/dna.py Fri Dec 17 00:58:54 2010 +0300
+++ b/allpy/dna.py Fri Dec 17 16:28:58 2010 +0300
@@ -1,16 +1,12 @@
import base

-class MonomerType(base.MonomerType):
+class Monomer(base.Monomer):
+ """DNA monomers: nucleotides."""
+ type = 'dna'
by_code1 = {}
by_code3 = {}
by_name = {}
-
-class Monomer(base.Monomer):
- """DNA monomers: nucleotides."""
- monomer_type = MonomerType
-
-MonomerType._initialize('d')
-MonomerType.instance_type = Monomer
+Monomer._initialize()

class Sequence(base.Sequence):
pass
diff -r 0435d9cc18d3 -r e3bcb9f8d7b0 allpy/protein.py
--- a/allpy/protein.py Fri Dec 17 00:58:54 2010 +0300
+++ b/allpy/protein.py Fri Dec 17 16:28:58 2010 +0300
@@ -1,16 +1,12 @@
import base

-class MonomerType(base.MonomerType):
+class Monomer(base.Monomer):
+ """Protein monomers: aminoacids."""
+ type = 'protein'
by_code1 = {}
by_code3 = {}
by_name = {}
-
-class Monomer(base.Monomer):
- """Protein monomers: aminoacids."""
- monomer_type = MonomerType
-
-MonomerType._initialize('p')
-MonomerType.instance_type = Monomer
+Monomer._initialize()

class Protein(list):
"""User defined protein; list of protein_sequences."""
diff -r 0435d9cc18d3 -r e3bcb9f8d7b0 allpy/rna.py
--- a/allpy/rna.py Fri Dec 17 00:58:54 2010 +0300
+++ b/allpy/rna.py Fri Dec 17 16:28:58 2010 +0300
@@ -1,16 +1,12 @@
import base

-class MonomerType(base.MonomerType):
+class Monomer(base.Monomer):
+ """RNA monomers: nucleotides."""
+ type = 'rna'
by_code1 = {}
by_code3 = {}
by_name = {}
-
-class Monomer(base.Monomer):
- """RNA monomers: nucleotides."""
- monomer_type = MonomerType
-
-MonomerType._initialize('r')
-MonomerType.instance_type = Monomer
+Monomer._initialize()

class Sequence(base.Sequence):
pass