setattr question

Gerard Flanagan grflanagan at yahoo.co.uk
Thu Mar 2 16:32:29 EST 2006


bruno at modulix wrote:
> Gerard Flanagan wrote:
> > Hello
> >
> > I have the following code:
> >
> > #### builder.py #########
> > class HtmlBuilder(object):
> >
> >     @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(text)
>
> 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 ?
>

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 'HtmlElementFactory' etait d'eviter ceci (cela?).  Il y a
une recette ici:

    http://aspn.activestate.com/ASPN/Cookbook/Python/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'.

> Err... I don't see the point of this class. Why not just calling the
> HtmlPage|Element|Literal classes directly ?
>
> > class HtmlElementFactory(object):
> >
> >     def __init__(self):
> >         for tag in ['li', 'ul']:
> >             setattr( self, tag, HtmlBuilder.element(tag) )
> >
> > #########################
> >
> > and so I can do the following:
> >
> >     html = HtmlElementFactory()
> >     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 = HtmlElementFactory()
> >     ul = html.ul( class='default' )
>
>
>
> >     for i in range(3):
> >         ul.append( html.li( 'ghfhj' )
> >     print ul.to_string()
>
> 'to_string' ?
> Let's see... 'to_string', a class with only staticmethods in it...
> You're coming from Java, aren't you ?-)
>

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(list):

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

    def write(self, writer):
        writer.start(self.tag, self.attrib)
        if self.text is not None:
            writer.data(self.text)
        for node in self:
            node.write(writer)
        writer.end()

    def to_string(self):
        out = StringIO()
        writer = HtmlWriter(out)
        self.write(writer)
        ret = out.getvalue()
        out.close()
        return ret

> (if yes, google for "python is not java", it may be helpful)
>
> > ie. to pass along *args and **kwargs to the HtmlElement constructor.
> > Any suggestions?
>
> yes : pass along *args and **kwargs to the HtmlElement constructor !-)
>
>
> > Or is there a better way to this kind of thing?
>
> 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
> overcomplexification.
>

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.

> What's wrong with:
>
> # nb: class is a reserved word in Python
> ul = HtmlElement('ul', css_class='default')
> for i in range(3):
>   ul.append(HtmlElement('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 at xiludom.gro'.split('@')])"

Merci bien pour votre reponse.

Gerard




More information about the Python-list mailing list