Easy "here documents" ??

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Jim Hill

    Easy "here documents" ??

    I've done some Googling around on this and it seems like creating a here
    document is a bit tricky with Python. Trivial via triple-quoted strings
    if there's no need for variable interpolation but requiring a long, long
    formatted arglist via (%s,%s,%s,ad infinitum) if there is. So my
    question is:

    Is there a way to produce a very long multiline string of output with
    variables' values inserted without having to resort to this wacky

    """v = %s"""%(variable )

    business?

    Thanks,


    Jim, Python no0b
    --
    "I regard NASCAR the same way I regard gay porn: I know it exists and I
    know some guys like it; I just don't want to see it." -- Z. B. Goode
  • Peter Hansen

    #2
    Re: Easy "here documents" ??

    Jim Hill wrote:[color=blue]
    > I've done some Googling around on this and it seems like creating a here
    > document is a bit tricky with Python. Trivial via triple-quoted strings
    > if there's no need for variable interpolation but requiring a long, long
    > formatted arglist via (%s,%s,%s,ad infinitum) if there is. So my
    > question is:
    >
    > Is there a way to produce a very long multiline string of output with
    > variables' values inserted without having to resort to this wacky
    >
    > """v = %s"""%(variable )
    >
    > business?[/color]

    I have no idea what a "here document" is, but there are several
    alternatives to the "wacky" basic substitution with a tuple of
    values.

    The simplest uses a mapping type:

    mydict = {'namedVal': 666}
    '''v = %(namedVal)s''' % mydict

    Does that let you build whatever a "here document" is?

    Comment

    • M.E.Farmer

      #3
      Re: Easy "here documents" ??

      I was curious so I googled , looks like a unix thing :)



      Ok I am with Peter on this , still clueless.
      What about string replacement.

      py> x = """ Hello me name is ~NAME~. \n I am ~AGE~ years old.\n
      .... I live in ~CITY~.\n The city of ~CITY~ is nice.\n
      .... I have live here for ~AGE~ years.\n
      .... """
      py> x = x.replace('~AGE ~', '12')
      py> x = x.replace('~NAM E~', 'Jimmy')
      py> x = x.replace('~CIT Y~', 'Oma')

      It makes your template cleaner cause you can use what you want
      for the tokens, but takes more lines to do the replacements.
      still clueless,
      M.E.Farmer


      Peter Hansen wrote:[color=blue]
      > Jim Hill wrote:[color=green]
      > > I've done some Googling around on this and it seems like creating a[/color][/color]
      here[color=blue][color=green]
      > > document is a bit tricky with Python. Trivial via triple-quoted[/color][/color]
      strings[color=blue][color=green]
      > > if there's no need for variable interpolation but requiring a long,[/color][/color]
      long[color=blue][color=green]
      > > formatted arglist via (%s,%s,%s,ad infinitum) if there is. So my
      > > question is:
      > >
      > > Is there a way to produce a very long multiline string of output[/color][/color]
      with[color=blue][color=green]
      > > variables' values inserted without having to resort to this wacky
      > >
      > > """v = %s"""%(variable )
      > >
      > > business?[/color]
      >
      > I have no idea what a "here document" is, but there are several
      > alternatives to the "wacky" basic substitution with a tuple of
      > values.
      >
      > The simplest uses a mapping type:
      >
      > mydict = {'namedVal': 666}
      > '''v = %(namedVal)s''' % mydict
      >
      > Does that let you build whatever a "here document" is?[/color]

      Comment

      • vincent wehren

        #4
        Re: Easy "here documents" ??

        Peter Hansen wrote:[color=blue]
        > Jim Hill wrote:
        >[color=green]
        >> I've done some Googling around on this and it seems like creating a here
        >> document is a bit tricky with Python. Trivial via triple-quoted strings
        >> if there's no need for variable interpolation but requiring a long, long
        >> formatted arglist via (%s,%s,%s,ad infinitum) if there is. So my
        >> question is:
        >>
        >> Is there a way to produce a very long multiline string of output with
        >> variables' values inserted without having to resort to this wacky
        >>
        >> """v = %s"""%(variable )
        >>
        >> business?[/color]
        >
        >
        > I have no idea what a "here document" is, but there are several
        > alternatives to the "wacky" basic substitution with a tuple of
        > values.[/color]

        OP is looking for "heredoc" syntax; in, let's say, PHP
        this lets you do something like:

        $foo = new foo();
        $name = 'MyName';

        echo <<<EOT
        My name is "$name". I am printing some $foo->foo.
        Now, I am printing some {$foo->bar[1]}.
        This should print a capital 'A': \x41
        EOT;

        AFAIK, there is no direct Python equivalent for this kind of syntax.
        Using a mapping like you suggested or the string.Template class in
        Python 2.4 still maybe improvements over what OP calls that "wacky"
        business.

        --
        Vincent Wehren
        [color=blue]
        >
        > The simplest uses a mapping type:
        >
        > mydict = {'namedVal': 666}
        > '''v = %(namedVal)s''' % mydict
        >
        > Does that let you build whatever a "here document" is?[/color]

        Comment

        • Nick Coghlan

          #5
          Re: Easy &quot;here documents&quot; ??

          Jim Hill wrote:[color=blue]
          > Is there a way to produce a very long multiline string of output with
          > variables' values inserted without having to resort to this wacky
          >
          > """v = %s"""%(variable )
          >
          > business?[/color]

          Try combining Python 2.4's subprocess module with its string Templates.

          Cheers,
          Nick.

          --
          Nick Coghlan | ncoghlan@email. com | Brisbane, Australia
          ---------------------------------------------------------------

          Comment

          • Jerry Sievers

            #6
            Re: Easy &quot;here documents&quot; ??

            jimhill@swcp.co m (Jim Hill) writes:
            [color=blue]
            > I've done some Googling around on this and it seems like creating a here
            > document is a bit tricky with Python. Trivial via triple-quoted strings
            > if there's no need for variable interpolation but requiring a long, long
            > formatted arglist via (%s,%s,%s,ad infinitum) if there is. So my
            > question is:
            >
            > Is there a way to produce a very long multiline string of output with
            > variables' values inserted without having to resort to this wacky
            >
            > """v = %s"""%(variable )
            > business?[/color]

            Hmmmmmm, by using the %(varname)[dsf...] with vars(), locals(),
            globals(), someDict, et al, a little messy but not terribly difficult.

            It gets uglier though if you want to do this from inside a function
            and have variables from more than one scope interpolated. For that
            you need something that can treat a series of dicts as one.If there's
            built in functionality in Python for this, I haven't discovered it
            yet.

            To wit;

            # feed this thing with one or more dicts, in order of decreasing
            #search priority.
            class multiDict:
            def __init__(self, *dicts):
            self.dicts = dicts
            def __getitem__(sel f, key):
            for dict in self.dicts:
            if dict.has_key(ke y):
            return dict[key]
            raise(KeyError)

            globalvar = 100

            def foo():
            localvar = 200

            print """
            %(globalvar)d
            %(localvar)d
            """ % multiDict(globa ls(), locals())

            foo()

            ------------------

            Now all else that we need to make this pretty would be macros, a la
            cpp m4 or similar

            define(`VARS', `multiDict(loca ls(), globals())')

            print "..." % VARS

            You get the idea.


            --
            -------------------------------------------------------------------------------
            Jerry Sievers 305 854-3001 (home) WWW ECommerce Consultant
            305 321-1144 (mobile http://www.JerrySievers.com/

            Comment

            • Fredrik Lundh

              #7
              Re: Easy &quot;here documents&quot; ??

              Jerry Sievers wrote:
              [color=blue]
              > It gets uglier though if you want to do this from inside a function
              > and have variables from more than one scope interpolated. For that
              > you need something that can treat a series of dicts as one.If there's
              > built in functionality in Python for this, I haven't discovered it
              > yet.[/color]

              you use them all the time: plain old instance objects...

              here's a rather horrid piece of code that turns a list of dictionaries
              into a single object the automatically searches the dictionary chain
              when you ask for attributes (use getattr for non-standard keys).

              def flatten_dicts(* dicts):
              root = None
              for dict in dicts:
              class wrapper: pass
              if root:
              wrapper.__bases __ = (root,)
              wrapper.__dict_ _ = dict
              root = wrapper
              return wrapper()

              obj = flatten_dicts(d 1, d2, d3)

              </F>



              Comment

              • Nick Craig-Wood

                #8
                Re: Easy &quot;here documents&quot; ??

                Jim Hill <jimhill@swcp.c om> wrote:[color=blue]
                > I've done some Googling around on this and it seems like creating a here
                > document is a bit tricky with Python. Trivial via triple-quoted strings
                > if there's no need for variable interpolation but requiring a long, long
                > formatted arglist via (%s,%s,%s,ad infinitum) if there is. So my
                > question is:
                >
                > Is there a way to produce a very long multiline string of output with
                > variables' values inserted without having to resort to this wacky
                >
                > """v = %s"""%(variable )[/color]

                I prefer this
                [color=blue][color=green][color=darkred]
                >>> amount = 1
                >>> cost = 2.0
                >>> what = 'potato'
                >>> print """\[/color][/color][/color]
                ... I'll have %(amount)s %(what)s
                ... for $%(cost)s please""" % locals()
                I'll have 1 potato
                for $2.0 please[color=blue][color=green][color=darkred]
                >>>[/color][/color][/color]

                Its almost as neat as perl / shell here documents and emacs parses """
                strings properly too ;-)

                Note the \ after the triple quote so the first line is flush on the
                left, and the locals() statement. You can use globals() or a
                dictionary you might have lying around instead which is much more
                flexible than perl. You can even pass self.__dict__ if you are in a
                class method so you can access attributes.
                [color=blue][color=green][color=darkred]
                >>> class A: pass[/color][/color][/color]
                ...[color=blue][color=green][color=darkred]
                >>> a=A()
                >>> a.amount=10
                >>> a.what="rutabag a"
                >>> a.cost=17.5
                >>> print """\[/color][/color][/color]
                ... I'll have %(amount)s %(what)s
                ... for $%(cost)s please""" % a.__dict__
                I'll have 10 rutabaga
                for $17.5 please[color=blue][color=green][color=darkred]
                >>>[/color][/color][/color]

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

                Comment

                • Keith Dart

                  #9
                  Re: Easy &quot;here documents&quot; ??

                  Jim Hill wrote:[color=blue]
                  > I've done some Googling around on this and it seems like creating a here
                  > document is a bit tricky with Python. Trivial via triple-quoted strings
                  > if there's no need for variable interpolation but requiring a long, long
                  > formatted arglist via (%s,%s,%s,ad infinitum) if there is. So my
                  > question is:
                  >
                  > Is there a way to produce a very long multiline string of output with
                  > variables' values inserted without having to resort to this wacky[/color]

                  I was thinking about this. But I can't think of any reason why you would
                  want to do this in Python. What's wrong with a regular parameterized
                  function?


                  --
                  -- ~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~ ~~~~~~~~~
                  Keith Dart <kdart@kdart.co m>
                  public key: ID: F3D288E4
                  =============== =============== =============== =============== =========

                  Comment

                  • Steve Holden

                    #10
                    Re: Easy &quot;here documents&quot; ??

                    Fredrik Lundh wrote:
                    [color=blue]
                    > Jerry Sievers wrote:
                    >
                    >[color=green]
                    >>It gets uglier though if you want to do this from inside a function
                    >>and have variables from more than one scope interpolated. For that
                    >>you need something that can treat a series of dicts as one.If there's
                    >>built in functionality in Python for this, I haven't discovered it
                    >>yet.[/color]
                    >
                    >
                    > you use them all the time: plain old instance objects...
                    >
                    > here's a rather horrid piece of code that turns a list of dictionaries
                    > into a single object the automatically searches the dictionary chain
                    > when you ask for attributes (use getattr for non-standard keys).
                    >
                    > def flatten_dicts(* dicts):
                    > root = None
                    > for dict in dicts:
                    > class wrapper: pass
                    > if root:
                    > wrapper.__bases __ = (root,)
                    > wrapper.__dict_ _ = dict
                    > root = wrapper
                    > return wrapper()
                    >
                    > obj = flatten_dicts(d 1, d2, d3)
                    >[/color]
                    Iterative subclassing, yet. Yerch :-) It's sometimes amazing just how
                    down and dirty Python will let you get.

                    Of course, if the mappings were all dictionaries then it would be rather
                    simpler to just update an empty dict with the outermost through to the
                    innermost scopes.

                    though-efficiency-would-be-determined-by-usage-ly y'rs - steve
                    --
                    Steve Holden http://www.holdenweb.com/
                    Python Web Programming http://pydish.holdenweb.com/
                    Holden Web LLC +1 703 861 4237 +1 800 494 3119

                    Comment

                    • Fredrik Lundh

                      #11
                      Re: Easy &quot;here documents&quot; ??

                      Steve Holden wrote:
                      [color=blue][color=green]
                      >> here's a rather horrid piece of code that turns a list of dictionaries
                      >> into a single object [that] automatically searches the dictionary chain
                      >> when you ask for attributes (use getattr for non-standard keys).
                      >>
                      >> def flatten_dicts(* dicts):
                      >> root = None
                      >> for dict in dicts:
                      >> class wrapper: pass
                      >> if root:
                      >> wrapper.__bases __ = (root,)
                      >> wrapper.__dict_ _ = dict
                      >> root = wrapper
                      >> return wrapper()
                      >>
                      >> obj = flatten_dicts(d 1, d2, d3)
                      >>[/color]
                      > Iterative subclassing, yet. Yerch :-) It's sometimes amazing just how down and dirty Python will
                      > let you get.[/color]

                      you can have a lot more fun with "class" than with "def"...
                      [color=blue]
                      > Of course, if the mappings were all dictionaries then it would be rather simpler to just update an
                      > empty dict with the outermost through to the innermost scopes.[/color]

                      except that if you do that, changes to the individual dictionaries won't
                      be visible in the "flattened" view.

                      </F>



                      Comment

                      • Scott David Daniels

                        #12
                        Re: Easy &quot;here documents&quot; ??

                        Nick Craig-Wood wrote:[color=blue]
                        > I prefer this
                        >[color=green][color=darkred]
                        > >>> amount = 1
                        > >>> cost = 2.0
                        > >>> what = 'potato'
                        > >>> print """\[/color][/color]
                        > ... I'll have %(amount)s %(what)s
                        > ... for $%(cost)s please""" % locals()
                        > I'll have 1 potato
                        > for $2.0 please[color=green][color=darkred]
                        > >>>[/color][/color][/color]

                        And if you enjoy building insecure stuff, try:

                        def fix(text, globals_=None, locals=None, quote='"'):
                        d = (globals_ or locals or globals()).copy ()
                        source = text.split(quot e)
                        source[1::2] = (str(eval(expr, d, locals or d))
                        for expr in source[1::2])
                        return ''.join(source)


                        amount = 1
                        cost = 2.0
                        what = 'potato'
                        print fix("""I'll have "amount" "what"s
                        for "'$%.2f' % cost"s please""", locals())


                        --Scott David Daniels
                        Scott.Daniels@A cm.Org

                        Comment

                        • Fredrik Lundh

                          #13
                          Re: Easy &quot;here documents&quot; ??

                          Scott David Daniels wrote:
                          [color=blue]
                          > And if you enjoy building insecure stuff, try:
                          >
                          > def fix(text, globals_=None, locals=None, quote='"'):
                          > d = (globals_ or locals or globals()).copy ()
                          > source = text.split(quot e)
                          > source[1::2] = (str(eval(expr, d, locals or d))
                          > for expr in source[1::2])
                          > return ''.join(source)
                          >
                          >
                          > amount = 1
                          > cost = 2.0
                          > what = 'potato'
                          > print fix("""I'll have "amount" "what"s
                          > for "'$%.2f' % cost"s please""", locals())[/color]

                          And if you prefer not to type so much:

                          def I(*args): return "".join(map(str , args))
                          def F(v, fmt): return ("%" + fmt) % v

                          print I("I'll have ", amount, " ", what, "s for $", F(cost, ".2f"), "s please")

                          </F>



                          Comment

                          • Doug Holton

                            #14
                            Re: Easy &quot;here documents&quot; ??

                            Jim Hill wrote:
                            [color=blue]
                            > Is there a way to produce a very long multiline string of output with
                            > variables' values inserted without having to resort to this wacky
                            >
                            > """v = %s"""%(variable )
                            >[/color]

                            No, not without the god-awful hacks you've already seen.

                            But it is possible in boo: : http://boo.codehaus.org/
                            See http://boo.codehaus.org/String+Interpolation

                            variable1 = 1
                            variable2 = 2

                            s = """
                            v = ${variable1}
                            v2's value is: ${variable2}
                            """

                            print s

                            Comment

                            • Bengt Richter

                              #15
                              Re: Easy &quot;here documents&quot; ??

                              On Sun, 19 Dec 2004 16:46:34 +0100, "Fredrik Lundh" <fredrik@python ware.com> wrote:
                              [color=blue]
                              >Jerry Sievers wrote:
                              >[color=green]
                              >> It gets uglier though if you want to do this from inside a function
                              >> and have variables from more than one scope interpolated. For that
                              >> you need something that can treat a series of dicts as one.If there's
                              >> built in functionality in Python for this, I haven't discovered it
                              >> yet.[/color]
                              >
                              >you use them all the time: plain old instance objects...
                              >
                              >here's a rather horrid piece of code that turns a list of dictionaries
                              >into a single object the automatically searches the dictionary chain
                              >when you ask for attributes (use getattr for non-standard keys).
                              >
                              >def flatten_dicts(* dicts):
                              > root = None
                              > for dict in dicts:
                              > class wrapper: pass
                              > if root:
                              > wrapper.__bases __ = (root,)
                              > wrapper.__dict_ _ = dict
                              > root = wrapper
                              > return wrapper()
                              >
                              >obj = flatten_dicts(d 1, d2, d3)
                              >[/color]
                              That's one I hadn't thought of in any form, but I'm glad to have been
                              shown the opening (although I am bit surprised at such dark side stuff
                              from you, even with the "horrid piece of code" qualification ;-)

                              Seriously, has anyone done a definitive documentation of
                              all the namespaces (incl name-search paths and r/w rules) of Python?
                              ISTM the name access games are a bit irregular. The difficulty of creating
                              a mapping usable like

                              txt = 'bim bam %(boo)s' % mapping

                              that will do _exactly_ the same thing as

                              txt = 'bim bam %s' % (boo,)

                              no matter whether boo is local, global, or a closure cell is symptomatic, ISTM.
                              flattendicts(lo cals(), globals()) is close, but not quite there due to locals()'s
                              being only a snapshot and leaving out closure cells -- is the latter intentional BTW?
                              ISTM closure cell variables belong somewhere, and it can't be in globals().

                              If every local context had a magic __localnamespac e__ object so that

                              assert __localnamespac e__.x is x and __localnamespac e__['x'] is x

                              never failed in any local context except with NameError, you could do lots
                              of things easily. Might not be so easy to implement though. But with __getattr__
                              and __getitem__ doing the same access,

                              txt = 'bim bam %(boo)s' % __localnamespac e__

                              would do what one might like. A sys._getframe(d epth).f_localna mespace
                              frame attribute as a way of peeking into various local namespaces via their
                              __localnamespac e__ objects might make name-chasing easier and more regular
                              there too. Just a thought, not thought out ;-)

                              Regards,
                              Bengt Richter

                              Comment

                              Working...