FAQ
Hi,

Im trying to find the best way to do a certain task and my so far I
have found that using something similar to factory pattern might be
the best bet.

I m parsing a file to be stored as a graph (using NetworkX). Each row
in the file corresponds to a node in the graph. However rows have
different types and different numbers of attributes. ( and their
corresponding nodes in the future will have methods )
eg

chr1 SGD gene 5 8 id=1 name=3 dbref=6
chr1 SGD intron 5 6 id=5 notes="spam"
chr1 SGD exon 7 8 id=5

so I was thinking of having a factory class to return the individual
objects for each row......ie

class Factory():
# if passed a gene return a gene object
# if passed an intron return an intron object
# if passed an exom return an exon object

Is this a good way of doing this, or is there a better way to do this
in Python, this is probably the way I d do it in Java.

Many Thanks

Nathan

Search Discussions

  • Fredrik Lundh at Dec 7, 2006 at 8:31 am

    Nathan Harmston wrote:

    so I was thinking of having a factory class to return the individual
    objects for each row......ie

    class Factory():
    # if passed a gene return a gene object
    # if passed an intron return an intron object
    # if passed an exom return an exon object

    Is this a good way of doing this, or is there a better way to do this
    in Python
    in python, that's spelled:

    def factory(...):
    # if passed a gene return a gene object
    # if passed an intron return an intron object
    # if passed an exom return an exon object

    </F>
  • Gabriel Genellina at Dec 7, 2006 at 8:47 am

    At Thursday 7/12/2006 05:28, Nathan Harmston wrote:
    chr1 SGD gene 5 8 id=1 name=3 dbref=6
    chr1 SGD intron 5 6 id=5 notes="spam"
    chr1 SGD exon 7 8 id=5

    so I was thinking of having a factory class to return the individual
    objects for each row......ie

    class Factory():
    # if passed a gene return a gene object
    # if passed an intron return an intron object
    # if passed an exom return an exon object

    Is this a good way of doing this, or is there a better way to do this
    in Python, this is probably the way I d do it in Java.
    The basic idea is the same, but instead of a long series of
    if...elif...else you can use a central registry (a dictionary will
    do) and dispatch on the name. Classes act as their own factories.

    registry = {}

    class Base(object):
    kind = "Unknown"
    register(Base)

    class Gene(Base):
    kind = "gene"
    def __init__(self, *args, **kw): pass
    register(Gene)

    class Intron(Base):
    kind = "intron"
    def __init__(self, *args, **kw): pass
    register(Intron)

    def register(cls):
    registry[cls.kind] = cls

    def factory(kind, *args, **kw):
    return registry[kind](*args, **kw)

    If some arguments are always present, you can name them, you're not
    limited to use the generic *args and **kw.


    --
    Gabriel Genellina
    Softlab SRL

    __________________________________________________
    Correo Yahoo!
    Espacio para todos tus mensajes, antivirus y antispam ?gratis!
    ?Abr? tu cuenta ya! - http://correo.yahoo.com.ar
  • Jan Dries at Dec 7, 2006 at 9:31 am

    Gabriel Genellina wrote:
    At Thursday 7/12/2006 05:28, Nathan Harmston wrote:
    so I was thinking of having a factory class to return the individual
    objects for each row......ie

    class Factory():
    # if passed a gene return a gene object
    # if passed an intron return an intron object
    # if passed an exom return an exon object

    Is this a good way of doing this, or is there a better way to do this
    in Python, this is probably the way I d do it in Java.
    The basic idea is the same, but instead of a long series of
    if...elif...else you can use a central registry (a dictionary will do)
    and dispatch on the name. Classes act as their own factories.

    registry = {}

    class Base(object):
    kind = "Unknown"
    register(Base)

    class Gene(Base):
    kind = "gene"
    def __init__(self, *args, **kw): pass
    register(Gene)

    class Intron(Base):
    kind = "intron"
    def __init__(self, *args, **kw): pass
    register(Intron)

    def register(cls):
    registry[cls.kind] = cls

    def factory(kind, *args, **kw):
    return registry[kind](*args, **kw)
    And by using a metaclass on Base you can add the wizardry to have the
    register-function called automatically whenever a class is derived from
    Base. I also tend to use the class name instead of a separate "kind"
    attribute.

    registry = {}

    class MetaBase(type):
    def __init__(cls, name, bases, dict):
    registry[name] = cls

    class Base(object):
    __metaclass__ = MetaBase

    class Gene(Base):
    def __init__(self, *args, **kw): pass

    class Intron(Base):
    def __init__(self, *args, **kw): pass

    def factory(kind, *args, **kw):
    return registry[kind](*args, **kw)


    That way you don't have to think about calling the register-function
    each time you derive a new class.

    Regards,
    Jan
  • Nick Craig-Wood at Dec 7, 2006 at 10:30 am

    Gabriel Genellina wrote:
    The basic idea is the same, but instead of a long series of
    if...elif...else you can use a central registry (a dictionary will
    do) and dispatch on the name. Classes act as their own factories.

    registry = {}

    class Base(object):
    kind = "Unknown"
    register(Base)

    class Gene(Base):
    kind = "gene"
    def __init__(self, *args, **kw): pass
    register(Gene)

    class Intron(Base):
    kind = "intron"
    def __init__(self, *args, **kw): pass
    register(Intron)

    def register(cls):
    registry[cls.kind] = cls

    def factory(kind, *args, **kw):
    return registry[kind](*args, **kw)

    If some arguments are always present, you can name them, you're not
    limited to use the generic *args and **kw.
    If you don't want to use a register() function on each class you could
    introspect like this (untested) to make the registry :-

    registry = {}
    for obj in sys.modules[__name__].__dict__.values():
    try:
    if issubclass(obj, Base):
    registry[kind] = obj
    except TypeError:
    pass

    There might be a neater way of writing the above!

    --
    Nick Craig-Wood <nick at craig-wood.com> -- http://www.craig-wood.com/nick

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouppython-list @
categoriespython
postedDec 7, '06 at 8:28a
activeDec 7, '06 at 10:30a
posts5
users5
websitepython.org

People

Translate

site design / logo © 2022 Grokbase