setattr question

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Gerard Flanagan

    #1

    setattr question

    Hello

    I have the following code:

    #### builder.py #########
    class HtmlBuilder(obj ect):

    @staticmethod
    def page(title=''):
    return HtmlPage(title)

    @staticmethod
    def element(tag, text=None, **attribs):
    return HtmlElement(tag , text, **attribs)

    @staticmethod
    def literal(text):
    return HtmlLiteral(tex t)

    class HtmlElementFact ory(object):

    def __init__(self):
    for tag in ['li', 'ul']:
    setattr( self, tag, HtmlBuilder.ele ment(tag) )

    ############### ##########

    and so I can do the following:

    html = HtmlElementFact ory()
    ul = html.ul
    ul.attrib['class'] = 'default'
    for i in range(3):
    li = html.li
    li.text = 'ghfhj'
    ul.append(li)
    print ul.to_string()

    but what I'd like to do is:

    html = HtmlElementFact ory()
    ul = html.ul( class='default' )
    for i in range(3):
    ul.append( html.li( 'ghfhj' )
    print ul.to_string()

    ie. to pass along *args and **kwargs to the HtmlElement constructor.
    Any suggestions? Or is there a better way to this kind of thing?

    thanks

    Gerard

  • bruno at modulix

    #2
    Re: setattr question

    Gerard Flanagan wrote:[color=blue]
    > Hello
    >
    > I have the following code:
    >
    > #### builder.py #########
    > class HtmlBuilder(obj ect):
    >
    > @staticmethod
    > def page(title=''):
    > return HtmlPage(title)
    >
    > @staticmethod
    > def element(tag, text=None, **attribs):
    > return HtmlElement(tag , text, **attribs)
    >
    > @staticmethod
    > def literal(text):
    > return HtmlLiteral(tex t)[/color]

    Je ne vois pas très bien à quoi sert cette classe (à moins bien sûr
    qu'il y ait d'autre code). Pour ce que je vois là, pourquoi ne pas
    appeler directement les classes HtmlPage, HtmlElement et HtmlLiteral ?

    Err... I don't see the point of this class. Why not just calling the
    HtmlPage|Elemen t|Literal classes directly ?
    [color=blue]
    > class HtmlElementFact ory(object):
    >
    > def __init__(self):
    > for tag in ['li', 'ul']:
    > setattr( self, tag, HtmlBuilder.ele ment(tag) )
    >
    > ############### ##########
    >
    > and so I can do the following:
    >
    > html = HtmlElementFact ory()
    > ul = html.ul
    > ul.attrib['class'] = 'default'
    > for i in range(3):
    > li = html.li
    > li.text = 'ghfhj'
    > ul.append(li)
    > print ul.to_string()
    >
    > but what I'd like to do is:
    >
    > html = HtmlElementFact ory()
    > ul = html.ul( class='default' )[/color]


    [color=blue]
    > for i in range(3):
    > ul.append( html.li( 'ghfhj' )
    > print ul.to_string()[/color]

    'to_string' ?
    Let's see... 'to_string', a class with only staticmethods in it...
    You're coming from Java, aren't you ?-)

    (if yes, google for "python is not java", it may be helpful)
    [color=blue]
    > ie. to pass along *args and **kwargs to the HtmlElement constructor.
    > Any suggestions?[/color]

    yes : pass along *args and **kwargs to the HtmlElement constructor !-)

    [color=blue]
    > Or is there a better way to this kind of thing?[/color]

    yes again : kiss (Keep It Simple Stupid)

    There's not enough code to really grasp what you're trying to do, but
    from what I see, I'd say you're having a bad case of arbitrary
    overcomplexific ation.

    What's wrong with:

    # nb: class is a reserved word in Python
    ul = HtmlElement('ul ', css_class='defa ult')
    for i in range(3):
    ul.append(HtmlE lement('li', 'baaz%d' % i)

    # nb2: use the __str__() method of HtmlElement
    print str(ul)

    Python's philosophy is to make simple things simple (don't worry,
    there's still space for complex things -> descriptors, metaclasses etc).

    HTH
    --
    bruno desthuilliers
    python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
    p in 'onurb@xiludom. gro'.split('@')])"

    Comment

    • Fredrik Lundh

      #3
      Re: setattr question

      Gerard Flanagan wrote:
      [color=blue]
      > I have the following code:
      >
      > #### builder.py #########
      > class HtmlBuilder(obj ect):
      >
      > @staticmethod
      > def page(title=''):
      > return HtmlPage(title)
      >
      > @staticmethod
      > def element(tag, text=None, **attribs):
      > return HtmlElement(tag , text, **attribs)
      >
      > @staticmethod
      > def literal(text):
      > return HtmlLiteral(tex t)[/color]

      just curious, but what's the purpose of this class, and what gave
      you the idea to structure your program in this way ?

      </F>



      Comment

      • Gerard Flanagan

        #4
        Re: setattr question

        bruno at modulix wrote:[color=blue]
        > Gerard Flanagan wrote:[color=green]
        > > Hello
        > >
        > > I have the following code:
        > >
        > > #### builder.py #########
        > > class HtmlBuilder(obj ect):
        > >
        > > @staticmethod
        > > def page(title=''):
        > > return HtmlPage(title)
        > >
        > > @staticmethod
        > > def element(tag, text=None, **attribs):
        > > return HtmlElement(tag , text, **attribs)
        > >
        > > @staticmethod
        > > def literal(text):
        > > return HtmlLiteral(tex t)[/color]
        >
        > Je ne vois pas très bien à quoi sert cette classe (à moins bien sûr
        > qu'il y ait d'autre code). Pour ce que je vois là, pourquoi ne pas
        > appeler directement les classes HtmlPage, HtmlElement et HtmlLiteral ?
        >[/color]

        C'est une vaine tentative d'appliquer "the Factory Pattern" ! J'ai eu
        commence d'ecrire les classes 'ul(HtmlElement ), li(HtmlElement) , etc ',
        et le but de 'HtmlElementFac tory' etait d'eviter ceci (cela?). Il y a
        une recette ici:



        mais il utilise 'apply', qui est...blah

        I was trying to implement the factory pattern.
        The recipe above uses 'apply' which is deprecated according to the
        docs, and I suppose I was curious how to do the same sort of thing
        without 'apply'.
        [color=blue]
        > Err... I don't see the point of this class. Why not just calling the
        > HtmlPage|Elemen t|Literal classes directly ?
        >[color=green]
        > > class HtmlElementFact ory(object):
        > >
        > > def __init__(self):
        > > for tag in ['li', 'ul']:
        > > setattr( self, tag, HtmlBuilder.ele ment(tag) )
        > >
        > > ############### ##########
        > >
        > > and so I can do the following:
        > >
        > > html = HtmlElementFact ory()
        > > ul = html.ul
        > > ul.attrib['class'] = 'default'
        > > for i in range(3):
        > > li = html.li
        > > li.text = 'ghfhj'
        > > ul.append(li)
        > > print ul.to_string()
        > >
        > > but what I'd like to do is:
        > >
        > > html = HtmlElementFact ory()
        > > ul = html.ul( class='default' )[/color]
        >
        >
        >[color=green]
        > > for i in range(3):
        > > ul.append( html.li( 'ghfhj' )
        > > print ul.to_string()[/color]
        >
        > 'to_string' ?
        > Let's see... 'to_string', a class with only staticmethods in it...
        > You're coming from Java, aren't you ?-)
        >[/color]

        Never been to Java in my life!
        I don't know if I understand you, HtmlElement has a 'to_string' method
        but no static methods:

        class HtmlElement(lis t):

        def __init__(self, tag, text=None, **attrib):
        self.tag = tag
        self.text = text
        self.attrib = attrib

        def write(self, writer):
        writer.start(se lf.tag, self.attrib)
        if self.text is not None:
        writer.data(sel f.text)
        for node in self:
        node.write(writ er)
        writer.end()

        def to_string(self) :
        out = StringIO()
        writer = HtmlWriter(out)
        self.write(writ er)
        ret = out.getvalue()
        out.close()
        return ret
        [color=blue]
        > (if yes, google for "python is not java", it may be helpful)
        >[color=green]
        > > ie. to pass along *args and **kwargs to the HtmlElement constructor.
        > > Any suggestions?[/color]
        >
        > yes : pass along *args and **kwargs to the HtmlElement constructor !-)
        >
        >[color=green]
        > > Or is there a better way to this kind of thing?[/color]
        >
        > yes again : kiss (Keep It Simple Stupid)
        >
        > There's not enough code to really grasp what you're trying to do, but
        > from what I see, I'd say you're having a bad case of arbitrary
        > overcomplexific ation.
        >[/color]

        My code itself is just a learning project ( etant sans emploi a ce
        moment, moi-meme...) and it is no doubt a bit 'over-egged' at the
        minute, but it is a first attempt and I can always refactor later.
        [color=blue]
        > What's wrong with:
        >
        > # nb: class is a reserved word in Python
        > ul = HtmlElement('ul ', css_class='defa ult')
        > for i in range(3):
        > ul.append(HtmlE lement('li', 'baaz%d' % i)
        >
        > # nb2: use the __str__() method of HtmlElement
        > print str(ul)
        >
        > Python's philosophy is to make simple things simple (don't worry,
        > there's still space for complex things -> descriptors, metaclasses etc).
        >
        > HTH
        > --
        > bruno desthuilliers
        > python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
        > p in 'onurb@xiludom. gro'.split('@')])"[/color]

        Merci bien pour votre reponse.

        Gerard

        Comment

        • Gerard Flanagan

          #5
          Re: setattr question

          Fredrik Lundh wrote:[color=blue]
          > Gerard Flanagan wrote:
          >[color=green]
          > > I have the following code:
          > >
          > > #### builder.py #########
          > > class HtmlBuilder(obj ect):
          > >
          > > @staticmethod
          > > def page(title=''):
          > > return HtmlPage(title)
          > >
          > > @staticmethod
          > > def element(tag, text=None, **attribs):
          > > return HtmlElement(tag , text, **attribs)
          > >
          > > @staticmethod
          > > def literal(text):
          > > return HtmlLiteral(tex t)[/color]
          >
          > just curious, but what's the purpose of this class, and what gave
          > you the idea to structure your program in this way ?
          >
          > </F>[/color]

          In my defense, I can only quote Albert Einstein: "If we knew what it
          was we were doing, it would not be called research, would it?" I'm
          writing a script to generate a few relatively static webpages and
          upload them to a server, but it's as much a learning exercise as
          anything else - I have no formal programming education. I thought the
          Factory pattern would be appropriate here; the class you quote was a
          first attempt and i knew it was undoubtedly the wrong approach, so
          that's why i asked the group...

          Gerard

          Comment

          • Kent Johnson

            #6
            Re: setattr question

            Gerard Flanagan wrote:[color=blue]
            > http://aspn.activestate.com/ASPN/Coo...n/Recipe/86900
            >
            > mais il utilise 'apply', qui est...blah
            >
            > I was trying to implement the factory pattern.
            > The recipe above uses 'apply' which is deprecated according to the
            > docs, and I suppose I was curious how to do the same sort of thing
            > without 'apply'.[/color]

            Apply has been replaced by 'extended call syntax', that is why it is
            deprecated. Instead of
            return apply(self._fun ction,_args,_ka rgs)

            write
            return self._function( *_args, **_kargs)

            Kent

            Comment

            • bruno at modulix

              #7
              Re: setattr question

              bruno at modulix wrote:
              (snip)
              [color=blue]
              > Je ne vois pas très bien à quoi sert cette classe (à moins bien sûr
              > qu'il y ait d'autre code). Pour ce que je vois là, pourquoi ne pas
              > appeler directement les classes HtmlPage, HtmlElement et HtmlLiteral ?
              >[/color]
              oops, sorry, forgot to remove this before posting :(
              --
              bruno desthuilliers
              python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
              p in 'onurb@xiludom. gro'.split('@')])"

              Comment

              • bruno at modulix

                #8
                Re: setattr question

                Gerard Flanagan wrote:[color=blue]
                > bruno at modulix wrote:
                >[/color]
                (snip french)[color=blue]
                >
                > I was trying to implement the factory pattern.
                > The recipe above uses 'apply' which is deprecated according to the
                > docs, and I suppose I was curious how to do the same sort of thing
                > without 'apply'.[/color]

                def fun(*args, **kwargs):
                pass

                def otherfun(*args, **kwargs):
                fun(*args, **kwargs)
                [color=blue]
                >[color=green]
                >>Err... I don't see the point of this class. Why not just calling the
                >>HtmlPage|Elem ent|Literal classes directly ?
                >>
                >>[/color][/color]
                (snip)
                [color=blue][color=green]
                >>'to_string' ?
                >>Let's see... 'to_string', a class with only staticmethods in it...
                >>You're coming from Java, aren't you ?-)
                >>[/color]
                >
                > Never been to Java in my life![/color]

                bad guess.
                [color=blue]
                > I don't know if I understand you, HtmlElement has a 'to_string' method[/color]

                I don't know this HtmlElement class, nor where it comes from.
                'to_string()' (or is it toString() ?) is javaish. The pythonic idiom for
                this is implementing the __str__() method and calling str(obj) on the
                obj (which will call obj.__str__()). Hence my (bad) guess about you
                being a Javaer.
                [color=blue]
                > but no static methods:[/color]

                Not the HtmlElement class, but the HtmlBuilder one. Here again, a class
                defining only staticmethods is a pretty javaish idiom - in Python, we
                just use good old functions !-) (in a separate module if you want a
                separate namespace).
                [color=blue]
                > class HtmlElement(lis t):
                >
                > def __init__(self, tag, text=None, **attrib):
                > self.tag = tag
                > self.text = text
                > self.attrib = attrib
                >
                > def write(self, writer):
                > writer.start(se lf.tag, self.attrib)
                > if self.text is not None:
                > writer.data(sel f.text)
                > for node in self:
                > node.write(writ er)
                > writer.end()
                >
                > def to_string(self) :
                > out = StringIO()
                > writer = HtmlWriter(out)
                > self.write(writ er)
                > ret = out.getvalue()
                > out.close()
                > return ret
                >[/color]

                If it's your own code, you may want to rename this last method __str__().
                [color=blue][color=green]
                >>[color=darkred]
                >>>ie. to pass along *args and **kwargs to the HtmlElement constructor.
                >>>Any suggestions?[/color]
                >>
                >>yes : pass along *args and **kwargs to the HtmlElement constructor !-)
                >>
                >>[color=darkred]
                >>>Or is there a better way to this kind of thing?[/color]
                >>
                >>yes again : kiss (Keep It Simple Stupid)
                >>
                >>There's not enough code to really grasp what you're trying to do, but
                >>from what I see, I'd say you're having a bad case of arbitrary
                >>overcomplexif ication.
                >>[/color]
                >
                > My code itself is just a learning project ( etant sans emploi a ce
                > moment, moi-meme...) and it is no doubt a bit 'over-egged' at the
                > minute, but it is a first attempt and I can always refactor later.[/color]

                My experience is that it's far easier to start simple and add
                flexibility where needed than to simplify useless complexity. KISS,
                yagni and all that kind of things...
                [color=blue]
                >
                > Merci bien pour votre reponse.
                >[/color]
                You're welcome.

                BTW, there's also a french speaking python newsgroup at fr.comp.lang.py .

                --
                bruno desthuilliers
                python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
                p in 'onurb@xiludom. gro'.split('@')])"

                Comment

                • Gerard Flanagan

                  #9
                  Re: setattr question

                  bruno at modulix wrote:
                  [...][color=blue]
                  >
                  > I don't know this HtmlElement class, nor where it comes from.
                  > 'to_string()' (or is it toString() ?) is javaish. The pythonic idiom for
                  > this is implementing the __str__() method and calling str(obj) on the
                  > obj (which will call obj.__str__()). Hence my (bad) guess about you
                  > being a Javaer.
                  >[/color]

                  I've made this change, thanks. ( I had a year with C# so maybe that's
                  why I'm so idiomatically-challenged ! )
                  [color=blue]
                  > Not the HtmlElement class, but the HtmlBuilder one. Here again, a class
                  > defining only staticmethods is a pretty javaish idiom - in Python, we
                  > just use good old functions !-) (in a separate module if you want a
                  > separate namespace).
                  >[/color]

                  But it's personal preference, no? The functions were kind of related
                  and meaningless outside the module they were declared - but I'll take
                  it on board, anyway.

                  [...]
                  [color=blue]
                  >
                  > My experience is that it's far easier to start simple and add
                  > flexibility where needed than to simplify useless complexity. KISS,
                  > yagni and all that kind of things...
                  >[/color]

                  yagni - I'd never heard that one!

                  I've ditched the factory class in any case:


                  (FWIW)
                  [color=blue][color=green]
                  > >
                  > > Merci bien pour votre reponse.
                  > >[/color]
                  > You're welcome.
                  >
                  > BTW, there's also a french speaking python newsgroup at fr.comp.lang.py .
                  >[/color]

                  I wasn't aware of that, I'll have a lurk!

                  Thanks again.

                  Gerard
                  [color=blue]
                  > --
                  > bruno desthuilliers
                  > python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
                  > p in 'onurb@xiludom. gro'.split('@')])"[/color]

                  Comment

                  • bruno at modulix

                    #10
                    Re: setattr question

                    Gerard Flanagan wrote:[color=blue]
                    > bruno at modulix wrote:
                    > [...]
                    >[color=green]
                    >>I don't know this HtmlElement class, nor where it comes from.
                    >>'to_string( )' (or is it toString() ?) is javaish. The pythonic idiom for
                    >>this is implementing the __str__() method and calling str(obj) on the
                    >>obj (which will call obj.__str__()). Hence my (bad) guess about you
                    >>being a Javaer.
                    >>[/color]
                    >
                    >
                    > I've made this change, thanks. ( I had a year with C# so maybe that's
                    > why I'm so idiomatically-challenged ! )[/color]

                    Well, C# being somewhat inspired by Java...
                    [color=blue]
                    >[color=green]
                    >>Not the HtmlElement class, but the HtmlBuilder one. Here again, a class
                    >>defining only staticmethods is a pretty javaish idiom - in Python, we
                    >>just use good old functions !-) (in a separate module if you want a
                    >>separate namespace).
                    >>[/color]
                    >
                    > But it's personal preference, no?[/color]

                    Well, in Python, there are a lot of things that can be done the way you
                    like it, but are better done the idiomatic way. Python relies quite a
                    lot on conventions and idioms where other languages try to inforce
                    strict rules.
                    [color=blue]
                    > The functions were kind of related
                    > and meaningless outside the module they were declared -[/color]

                    FWIW (and from the snippet I saw), these functions are useless even in
                    the module !-)

                    Unless you want to dynamically choose the concrete class at runtime
                    based on platform/settings/phase of the moon/whatnot (which seems not to
                    be te case in the snippet you posted), you don't need these functions,
                    just instanciating the concrete class is enough. Remember that Python
                    classes *are* factory already - and that you can freely replace a class
                    by any callable returning an instance, ie:

                    == before refactoring, directly instanciating concrete class ==
                    # myhtmlmodule.py
                    class HtmlElement(tag , *args, **kw):
                    # code here

                    # myclientmodule. py
                    from myhtmlmodule import HtmlElement
                    ul = HtmlElement('ul ')


                    == after refactoring, using a factory function ==
                    # myhtmlmodule.py
                    class _HtmlElement1(t ag, *args, **kw):
                    # code here

                    class _HtmlElement2(t ag, *args, **kw):
                    # other code here

                    # yes, it's now a function...
                    def HtmlElement(tag , *args, **kw):
                    if phase_of_the_mo on():
                    klass = _HtmlElement1
                    else:
                    klass = _HtmlElement2
                    return klass(tag, *args, **kw)

                    # myclientmodule. py
                    # well... nothing changed here !-)
                    from myhtmlmodule import HtmlElement
                    ul = HtmlElement('ul ')


                    You could also do the trick with metaclass black magic, but what, KISS...
                    [color=blue]
                    > but I'll take
                    > it on board, anyway.
                    >
                    > [...]
                    >
                    >[color=green]
                    >>My experience is that it's far easier to start simple and add
                    >>flexibility where needed than to simplify useless complexity. KISS,
                    >>yagni and all that kind of things...
                    >>[/color]
                    >
                    > yagni - I'd never heard that one![/color]

                    You Aint Gonna Need It.

                    Code not written is the best code, so don't write code "just in case".
                    Python is usually dynamic enough to make refactoring easy (cf example above)
                    [color=blue]
                    > I've ditched the factory class in any case:
                    >
                    > http://gflanagan.net/site/python/htm...HtmlBuilder.py
                    > (FWIW)[/color]

                    Seems mostly clean. May I suggest a couple small corrections/improvements ?

                    1/ potential bugfix:
                    try:
                    from tidy import parseString
                    except ImportError:
                    def parseString(tex t):
                    # woops, this function is supposed to return something
                    #pass
                    return text

                    2/ safer and cleaner
                    class HtmlPage(HtmlEl ement):
                    # removed class vars,
                    # replaced with default in __init__
                    def __init__(self, title, **kw):
                    self.title = title
                    self.stylesheet s = kw.get('stylesh eets', [])
                    self.doctype = kw.get('doctype ', HTML4_STRICT)

                    [color=blue][color=green]
                    >>BTW, there's also a french speaking python newsgroup at fr.comp.lang.py .[/color]
                    >
                    > I wasn't aware of that, I'll have a lurk![/color]

                    see you there !-)
                    [color=blue][color=green]
                    >>--
                    >>bruno desthuilliers
                    >>python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
                    >>p in 'onurb@xiludom. gro'.split('@')])"[/color]
                    >
                    >[/color]


                    --
                    bruno desthuilliers
                    python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
                    p in 'onurb@xiludom. gro'.split('@')])"

                    Comment

                    • Gerard Flanagan

                      #11
                      Re: setattr question

                      bruno at modulix wrote:[color=blue]
                      > Gerard Flanagan wrote:[color=green]
                      > > The functions were kind of related
                      > > and meaningless outside the module they were declared -[/color]
                      >
                      > FWIW (and from the snippet I saw), these functions are useless even in
                      > the module !-)
                      >[/color]

                      ok, ok... :-)
                      [color=blue]
                      > Unless you want to dynamically choose the concrete class at runtime
                      > based on platform/settings/phase of the moon/whatnot (which seems not to
                      > be te case in the snippet you posted), you don't need these functions,
                      > just instanciating the concrete class is enough. Remember that Python
                      > classes *are* factory already - and that you can freely replace a class
                      > by any callable returning an instance, ie:
                      >
                      > == before refactoring, directly instanciating concrete class ==
                      > # myhtmlmodule.py
                      > class HtmlElement(tag , *args, **kw):
                      > # code here
                      >
                      > # myclientmodule. py
                      > from myhtmlmodule import HtmlElement
                      > ul = HtmlElement('ul ')
                      >
                      >
                      > == after refactoring, using a factory function ==
                      > # myhtmlmodule.py
                      > class _HtmlElement1(t ag, *args, **kw):
                      > # code here
                      >
                      > class _HtmlElement2(t ag, *args, **kw):
                      > # other code here
                      >
                      > # yes, it's now a function...
                      > def HtmlElement(tag , *args, **kw):
                      > if phase_of_the_mo on():
                      > klass = _HtmlElement1
                      > else:
                      > klass = _HtmlElement2
                      > return klass(tag, *args, **kw)
                      >
                      > # myclientmodule. py
                      > # well... nothing changed here !-)
                      > from myhtmlmodule import HtmlElement
                      > ul = HtmlElement('ul ')
                      >[/color]

                      ah, I'm getting it.
                      [color=blue]
                      >[color=green]
                      > > I've ditched the factory class in any case:
                      > >
                      > > http://gflanagan.net/site/python/htm...HtmlBuilder.py
                      > > (FWIW)[/color]
                      >
                      > Seems mostly clean. May I suggest a couple small corrections/improvements ?
                      >
                      > 1/ potential bugfix:
                      > try:
                      > from tidy import parseString
                      > except ImportError:
                      > def parseString(tex t):
                      > # woops, this function is supposed to return something
                      > #pass
                      > return text
                      >
                      > 2/ safer and cleaner
                      > class HtmlPage(HtmlEl ement):
                      > # removed class vars,
                      > # replaced with default in __init__
                      > def __init__(self, title, **kw):
                      > self.title = title
                      > self.stylesheet s = kw.get('stylesh eets', [])
                      > self.doctype = kw.get('doctype ', HTML4_STRICT)
                      >[/color]

                      That's much better - thanks very much for taking the time, I'm a little
                      bit wiser!

                      regards

                      Gerard
                      [color=blue]
                      > --
                      > bruno desthuilliers
                      > python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
                      > p in 'onurb@xiludom. gro'.split('@')])"[/color]

                      Comment

                      Working...