better way than: myPage += 'more html' , ...

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Gobo Borz

    better way than: myPage += 'more html' , ...

    Hi everyone,

    I have a python cgi program that uses print statements to write html.
    The program has grown, and for reasons I won't bore you with, I need to
    build the page in a string and "print" it at once.

    I remember reading somewhere that building the string with successive
    "+=" statements is inefficient, but I don't know any alternatives, and
    my search attempts came up empty. Is there a better, more efficient way
    to do it than this:

    #---------------------------------
    htmlPage = "<html><header> </header><body>"
    htmlPage += "more html"
    ....
    htmlPage += "even more html"
    ....
    htmlPage += "</body></html>"
    print htmlPage
    #-------------------------------------

    Thanks, Gobo

  • Alan Kennedy

    #2
    Re: better way than: myPage += 'more html' , ...

    Gobo Borz wrote:
    [color=blue]
    > I remember reading somewhere that building the string with successive
    > "+=" statements is inefficient, but I don't know any alternatives, and
    > my search attempts came up empty. Is there a better, more efficient way
    > to do it than this:
    >
    > #---------------------------------
    > htmlPage = "<html><header> </header><body>"
    > htmlPage += "more html"
    > ...
    > htmlPage += "even more html"
    > ...
    > htmlPage += "</body></html>"
    > print htmlPage
    > #-------------------------------------[/color]

    Best to do something like

    #---------------------------------

    htmlbits = []
    htmlbits.append ("<html><header ></header><body>")
    htmlbits.append ("more html")
    # ...
    htmlbits.append ("even more html")
    # ...
    htmlbits.append ("</body></html>")

    # And now for the non-intuitive bit
    print "".join(htmlbit s)

    #---------------------------------

    HTH,

    --
    alan kennedy
    -----------------------------------------------------
    check http headers here: http://xhaus.com/headers
    email alan: http://xhaus.com/mailto/alan

    Comment

    • Anthony Baxter

      #3
      Re: better way than: myPage += 'more html' , ...

      [color=blue][color=green][color=darkred]
      >>> Gobo Borz wrote[/color][/color]
      > I remember reading somewhere that building the string with successive
      > "+=" statements is inefficient, but I don't know any alternatives, and
      > my search attempts came up empty. Is there a better, more efficient way
      > to do it than this:
      >
      > #---------------------------------
      > htmlPage = "<html><header> </header><body>"
      > htmlPage += "more html"
      > ...
      > htmlPage += "even more html"
      > ...
      > htmlPage += "</body></html>"
      > print htmlPage
      > #-------------------------------------[/color]

      Instead, build up a list of strings, then join them all at
      the end - this way, the system only has to allocate the
      space once. Much quicker.

      #---------------------------------
      htmlPage = []
      htmlPage.append ("<html><header ></header><body>")
      htmlPage.append ("more html")
      ...
      htmlPage.append ("even more html")
      ...
      htmlPage.append ("</body></html>")
      page = ''.join(htmlPag e)
      print page
      #-------------------------------------

      Anthony

      Comment

      • Andy Jewell

        #4
        Re: better way than: myPage += 'more html' , ...

        On Wednesday 25 Jun 2003 5:20 pm, Gobo Borz wrote:[color=blue]
        > Hi everyone,
        >
        > I have a python cgi program that uses print statements to write html.
        > The program has grown, and for reasons I won't bore you with, I need to
        > build the page in a string and "print" it at once.
        >
        > I remember reading somewhere that building the string with successive
        > "+=" statements is inefficient, but I don't know any alternatives, and
        > my search attempts came up empty. Is there a better, more efficient way
        > to do it than this:
        >
        > #---------------------------------
        > htmlPage = "<html><header> </header><body>"
        > htmlPage += "more html"
        > ...
        > htmlPage += "even more html"
        > ...
        > htmlPage += "</body></html>"
        > print htmlPage
        > #-------------------------------------
        >
        > Thanks, Gobo[/color]


        An easy way, which requires little changes tou your code would be to use a
        list and join it up into a string in one go at the end:

        -----------8<--------------
        htmlPage=["<html><header> </header><body>\n "]
        htmlPage.append ("more html\n")
        ....
        htmlPage.append ("more html\n")
        ....
        htmlPage.append ("<\body><\html >\n")
        htmlDoc="".join (htmlPage)
        -----------8<--------------

        This is more efficient, as the string joining is done all at the same time,
        rather than in little chunks.

        hope that helps
        -andyj


        Comment

        • Gobo Borz

          #5
          Re: better way than: myPage += 'more html' , ...

          Thanks Alan, Anthony, and Andy! B's thru Z's need not respond, I have
          my answer.

          --Gobo


          Gobo Borz wrote:[color=blue]
          > Hi everyone,
          >
          > I have a python cgi program that uses print statements to write html.
          > The program has grown, and for reasons I won't bore you with, I need to
          > build the page in a string and "print" it at once.
          >
          > I remember reading somewhere that building the string with successive
          > "+=" statements is inefficient, but I don't know any alternatives, and
          > my search attempts came up empty. Is there a better, more efficient way
          > to do it than this:
          >
          > #---------------------------------
          > htmlPage = "<html><header> </header><body>"
          > htmlPage += "more html"
          > ...
          > htmlPage += "even more html"
          > ...
          > htmlPage += "</body></html>"
          > print htmlPage
          > #-------------------------------------
          >
          > Thanks, Gobo
          >[/color]

          Comment

          • Gobo Borz

            #6
            Re: better way than: myPage += 'more html' , ...

            Thanks, that opens up a world of possibilities I haven't began to
            explore. In general, I'm not fond of templating systems because of the
            overhead, but it seems as your suggestion might be fast, since it uses
            ordinary string substitution.

            --Gobo

            mirko-lists@zeibig.ne t wrote:[color=blue]
            > In article <3EF9CBCB.90305 @yahoo.com>, Gobo Borz wrote:
            >[color=green]
            >>I remember reading somewhere that building the string with successive
            >>"+=" statements is inefficient, but I don't know any alternatives, and
            >>my search attempts came up empty. Is there a better, more efficient way
            >>to do it than this:
            >>
            >>#---------------------------------
            >>htmlPage = "<html><header> </header><body>"
            >>htmlPage += "more html"
            >>...
            >>htmlPage += "even more html"
            >>...
            >>htmlPage += "</body></html>"
            >>print htmlPage
            >>#-------------------------------------[/color]
            >
            > Hello Gobo,
            >
            > you may use the list solution provided in the former chapters. Some other
            > solution would be to use string substitution:
            > --------- snip -----------
            > htmlPage = """
            > <html>
            > <head>
            > <title>%(title) s</title>
            > </head>
            > <body>
            > <h1>%(title)s </h1>
            > %(body)s
            > </body>
            > </html>
            > """
            >
            > body = []
            > body.append("<p >my first snippet</p>")
            > body.append("<u l>")
            > for in range(10):
            > body.append(""" <li>%s. entry</li>""" % i)
            > body.append("</ul>")
            >
            > contents = { "title": "My Foopage",
            > "body": "\n".join(b ody) }
            >
            > print htmlPage % contents
            > -------- snap -------------
            >
            > This type of substitution goes for a very simple templating system.
            >
            > Best Regards
            > Mirko
            >[/color]

            Comment

            • Gerrit Holl

              #7
              Re: better way than: myPage += 'more html' , ...

              Gobo Borz wrote:[color=blue]
              > I have a python cgi program that uses print statements to write html.
              > The program has grown, and for reasons I won't bore you with, I need to
              > build the page in a string and "print" it at once.[/color]

              Another way, which has not yet been mentioned but which I like much,
              is the cStringIO module. You can write to a string as if it is a
              file:

              0 >>> import cStringIO
              1 >>> mystr = cStringIO.Strin gIO()
              2 >>> mystr.write("<h tml")
              3 >>> mystr.write("<b ody>")
              4 >>> mystr.write("<h 1>Header</h1>")
              5 >>> mystr.write("<p >Hello, world!</p>")
              6 >>> mystr.write("</body></html>")
              10 >>> mystr.getvalue( )
              '<html<body><h1 >Header</h1><p>Hello, world!</p></body></html>'

              The cStringIO module is documented at:



              cStringIO is a faster C implementation with the same API.

              yours,
              Gerrit.

              --
              196. If a man put out the eye of another man, his eye shall be put out.
              -- 1780 BC, Hammurabi, Code of Law
              --
              Asperger Syndroom - een persoonlijke benadering:

              Het zijn tijden om je zelf met politiek te bemoeien:
              De website van de Socialistische Partij (SP) in Nederland: Informatie, nieuws, agenda en publicaties.


              Comment

              • Max M

                #8
                Re: better way than: myPage += 'more html' , ...

                #Gobo Borz wrote:
                #> Thanks, that opens up a world of possibilities I haven't began to
                #> explore. In general, I'm not fond of templating systems because of the
                #> overhead, but it seems as your suggestion might be fast, since it uses
                #> ordinary string substitution.
                #

                Often an adapter is a good choice:


                class HtmlViewAdapter :

                """
                Base class that Adapts any object to html output.
                """

                def __init__(self, obj):
                self._obj = obj

                def __getattr__(sel f, attr):
                "Returns values for the attributes"
                return getattr(self._o bj, attr)

                def __getitem__(sel f, item):
                "get attrs as items for use in string formatting templates"
                value = getattr(self, item)
                if callable(value) :
                return value()
                else:
                return value

                import time

                class SomeObject:

                "The object we want displayed in html"


                def __init__(self):
                self.id = 42
                self.now = time.localtime( )
                self.title = 'the title'



                class SomeObjectHtmlV iew(HtmlViewAda pter):

                """
                an adapter for the object, here you can fine adjust, format dates
                etc.
                """

                def title(self):
                return self._obj.title .upper()

                def now(self):
                return time.strftime(' %y:%m:%d %H-%M-%S',self._obj.n ow)


                view = SomeObjectHtmlV iew(SomeObject( ))

                print '<a href="%(id)s">% (title)s</a> <i>%(now)s</i>' % view[color=blue][color=green][color=darkred]
                >>> <a href="42">THE TITLE</a> <i>03:06:26 00-12-16</i>[/color][/color][/color]

                Comment

                • Thomas Güttler

                  #9
                  Re: better way than: myPage += 'more html' , ...

                  Gobo Borz wrote:
                  [color=blue]
                  > Hi everyone,
                  >
                  > I have a python cgi program that uses print statements to write html.
                  > The program has grown, and for reasons I won't bore you with, I need to
                  > build the page in a string and "print" it at once.[/color]

                  Hi!

                  I do it like this:

                  def foo(mydict):
                  ret=[]

                  rows=[]
                  for key, value in mydict.items():
                  rows.append('<t r><td>%s</td><td>%s</td></tr>' % (key, value))
                  rows=''.join(ro ws)

                  ret.append('<ta ble>%s</table>' % rows)
                  return ''.join(ret)

                  I try to keep the start-tag and the end-tag in one string.
                  This keeps the code from becomming ugly.

                  thomas

                  Comment

                  • François Pinard

                    #10
                    Re: better way than: myPage += 'more html' , ...

                    [Max M]
                    [color=blue]
                    > I remember reading a post where I saw meassurements that showed it to be
                    > twice as fast. I was too lazy too google it. But here goes. [...][/color]

                    [Adrien Di Mascio]
                    [color=blue]
                    > I've a made a quite basic test on these methods : [...][/color]

                    Thanks to both! Have a good day!

                    --
                    François Pinard http://www.iro.umontreal.ca/~pinard

                    Comment

                    • Fredrik Lundh

                      #11
                      Re: better way than: myPage += 'more html' , ...

                      Adrien Di Mascio wrote:
                      [color=blue]
                      > I've a made a quite basic test on these methods :
                      >
                      > /snip/
                      >
                      > def write_thousands _join(self, char):
                      > """Writes a 100000 times 'char' in a list and joins it
                      > """
                      > str_list = []
                      > for index in range(100000):
                      > str_list.append (char)
                      >
                      > return ''.join(str_lis t)[/color]

                      no time to repeat your tests, but

                      def write_thousands _join(self, char):
                      """Writes a 100000 times 'char' in a list and joins it
                      """
                      str_list = []
                      append = str_list.append # bind method to local variable
                      for index in range(100000):
                      append(char)

                      return ''.join(str_lis t)

                      "should" be slightly faster.

                      also note that the results "may" differ somewhat if you append strings
                      of different lengths (mostly due to different overallocation strategies;
                      or maybe they're not different anymore; cannot remember...)

                      I always use join, but that's probably because that method is more likely
                      to run code that I once wrote. Never trust code written by a man who
                      uses defines to create his own C syntax ;-)

                      </F>




                      Comment

                      • Chuck Spears

                        #12
                        Re: better way than: myPage += 'more html' , ...

                        I have a question with regards to the sprintf style of replacing
                        strings. I have a table in my HTML with a 50% width specifier. How
                        can i get the formatter to ignore it. For example in the example
                        below how can i code the 50% to be ignored?

                        keep the "%s 50% %s" % ("a","b")

                        Comment

                        Working...