By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,677 Members | 1,174 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,677 IT Pros & Developers. It's quick & easy.

Easy "here documents" ??

P: n/a
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
Jul 18 '05 #1
Share this Question
Share on Google+
33 Replies


P: n/a
Jim Hill wrote:
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?


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?
Jul 18 '05 #2

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

http://www.faqs.org/docs/abs/HTML/here-docs.html

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('~NAME~', 'Jimmy')
py> x = x.replace('~CITY~', '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:
Jim Hill wrote:
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?


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?


Jul 18 '05 #3

P: n/a
Peter Hansen wrote:
Jim Hill wrote:
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?

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


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

The simplest uses a mapping type:

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

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

Jul 18 '05 #4

P: n/a
Jim Hill wrote:
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?


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

Cheers,
Nick.

--
Nick Coghlan | nc******@email.com | Brisbane, Australia
---------------------------------------------------------------
http://boredomandlaziness.skystorm.net
Jul 18 '05 #5

P: n/a
ji*****@swcp.com (Jim Hill) writes:
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?


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__(self, key):
for dict in self.dicts:
if dict.has_key(key):
return dict[key]
raise(KeyError)

globalvar = 100

def foo():
localvar = 200

print """
%(globalvar)d
%(localvar)d
""" % multiDict(globals(), locals())

foo()

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

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

define(`VARS', `multiDict(locals(), globals())')

print "..." % VARS

You get the idea.
--
-------------------------------------------------------------------------------
Jerry Sievers 305 854-3001 (home) WWW ECommerce Consultant
305 321-1144 (mobile http://www.JerrySievers.com/
Jul 18 '05 #6

P: n/a
Jerry Sievers wrote:
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.


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(d1, d2, d3)

</F>

Jul 18 '05 #7

P: n/a
Jim Hill <ji*****@swcp.com> wrote:
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)


I prefer this
amount = 1
cost = 2.0
what = 'potato'
print """\ ... I'll have %(amount)s %(what)s
... for $%(cost)s please""" % locals()
I'll have 1 potato
for $2.0 please
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.
class A: pass ... a=A()
a.amount=10
a.what="rutabaga"
a.cost=17.5
print """\ ... I'll have %(amount)s %(what)s
... for $%(cost)s please""" % a.__dict__
I'll have 10 rutabaga
for $17.5 please


--
Nick Craig-Wood <ni**@craig-wood.com> -- http://www.craig-wood.com/nick
Jul 18 '05 #8

P: n/a
Jim Hill wrote:
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


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 <kd***@kdart.com>
public key: ID: F3D288E4
================================================== ===================
Jul 18 '05 #9

P: n/a
Fredrik Lundh wrote:
Jerry Sievers wrote:

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.

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(d1, d2, d3)

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
Jul 18 '05 #10

P: n/a
Steve Holden wrote:
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(d1, d2, d3)
Iterative subclassing, yet. Yerch :-) It's sometimes amazing just how down and dirty Python will
let you get.


you can have a lot more fun with "class" than with "def"...
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.


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

</F>

Jul 18 '05 #11

P: n/a
Nick Craig-Wood wrote:
I prefer this
>>> amount = 1
>>> cost = 2.0
>>> what = 'potato'
>>> print """\ ... I'll have %(amount)s %(what)s
... for $%(cost)s please""" % locals()
I'll have 1 potato
for $2.0 please >>>


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(quote)
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
Sc***********@Acm.Org
Jul 18 '05 #12

P: n/a
Scott David Daniels wrote:
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(quote)
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())


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>

Jul 18 '05 #13

P: n/a
Jim Hill wrote:
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)


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
Jul 18 '05 #14

P: n/a
On Sun, 19 Dec 2004 16:46:34 +0100, "Fredrik Lundh" <fr*****@pythonware.com> wrote:
Jerry Sievers wrote:
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.


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(d1, d2, d3)

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(locals(), 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 __localnamespace__ object so that

assert __localnamespace__.x is x and __localnamespace__['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' % __localnamespace__

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

Regards,
Bengt Richter
Jul 18 '05 #15

P: n/a

"Jim Hill" <ji*****@swcp.com> wrote in message
news:cq**********@iruka.swcp.com...
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?
The major issue here is that both ways of text substitution
in Python are based on the C and C++ printf statement.
Here documents are based on a much less disciplined
use of variables; they use the local variables on the
calling stack.

It would certainly be possible to write a module that
substitutes the values of variables in the calling stack.
Look at the inspect module in the Python Runtime
Services section of the Python Library for the basic
facilities you'd need to use to write such a module.

I'm not sure why you'd want to do this, though.
It seems like it would be mostly useful in a style
of programming that's quite foreign to the way
Python wants to be programmed.

John Roth


Thanks,
Jim, Python no0b


Jul 18 '05 #16

P: n/a
Nick Craig-Wood wrote:
Jim Hill <ji*****@swcp.com> wrote:
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)
I prefer this

... I'll have %(amount)s %(what)s
... for $%(cost)s please""" % locals()
Looks pretty slick. This might just be what I need.
Its almost as neat as perl / shell here documents and emacs parses """
strings properly too ;-)


Mmm...emacs...

Thanks for the tip.
Jim
--
"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
Jul 18 '05 #17

P: n/a
Fredrik Lundh wrote:
Scott David Daniels wrote:
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(quote)
source[1::2] = (str(eval(expr, d, locals or d))
for expr in source[1::2])
return ''.join(source)

And if you prefer not to type so much:

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


Not that I don't appreciate the suggestions from masters of the Python
universe, but the reason I'm switching to Python from Perl is for the
readability. What you fells are suggesting might as well be riddled
with dollar signs and semicolons... <emoticon>.
Jim
--
"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
Jul 18 '05 #18

P: n/a
Keith Dart wrote:
Jim Hill wrote:
Is there a way to produce a very long multiline string of output with
variables' values inserted without having to resort to this wacky


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?


I'm trying to write a script that writes a script for a rather specialized
task. I know that seems weird, but the original version was written in
Korn shell and most of my team are familiar with the way it does things
even though they don't read Korn. (The original author has since
decamped for greener pastures.) Since we're trying to standardize all
our scripts on Python I got the task of rewriting. Once I have the
simple port done I'll see if I can't figure out A Better Way.
Jim
--
"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
Jul 18 '05 #19

P: n/a
John Roth wrote:

[Here docs]
I'm not sure why you'd want to do this, though.
It seems like it would be mostly useful in a style
of programming that's quite foreign to the way
Python wants to be programmed.


I'm going to try some of the suggestions that others have floated but I
think you've really tumbled to the core of my situation: Trying to take
a Korn shell script and convert it as closely to line-for-line into
Python as possible is Just Dumb.
Jim
--
"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
Jul 18 '05 #20

P: n/a
Jim Hill wrote:
And if you prefer not to type so much:

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


Not that I don't appreciate the suggestions from masters of the Python
universe, but the reason I'm switching to Python from Perl is for the
readability. What you fells are suggesting might as well be riddled
with dollar signs and semicolons... <emoticon>.


the I and F functions? add newlines to them, and replace that ugly-but-
generally-accepted "".join thing with a proper string.join call, split the
second expression into two subexpressions if necessary, and they'll
look a lot better.

or did you mean the call to I? did you look at it in a syntax-coloring
editor?

</F>

Jul 18 '05 #21

P: n/a
Jim Hill wrote:
I'm trying to write a script that writes a script for a rather specialized
task. I know that seems weird, but the original version was written in
Korn shell and most of my team are familiar with the way it does things
even though they don't read Korn.


so why didn't you tell us? ;-)

if you want $-style interpolation, you can use the new string.Template
class (mentioned in passing by Nick above); useful examples here:

http://aspn.activestate.com/ASPN/Coo.../Recipe/304004

if you don't have 2.4, you can use the RE machinery for the same purpose;
see e.g.

http://effbot.org/zone/re-sub.htm#simple-templating

</F>

Jul 18 '05 #22

P: n/a
Fredrik Lundh wrote:
Jim Hill wrote:

I'm trying to write a script that writes a script for a rather specialized
task. I know that seems weird, but the original version was written in
Korn shell and most of my team are familiar with the way it does things
even though they don't read Korn.

so why didn't you tell us? ;-)

if you want $-style interpolation, you can use the new string.Template
class (mentioned in passing by Nick above); useful examples here:

http://aspn.activestate.com/ASPN/Coo.../Recipe/304004

if you don't have 2.4, you can use the RE machinery for the same purpose;
see e.g.

http://effbot.org/zone/re-sub.htm#simple-templating


You might also try the following:

---------python--------------
# a self-substituting string object. Just set attribute names to mapping
names
# that are given in the initializer string.
class mapstr(str):
def __new__(cls, initstr, **kwargs):
s = str.__new__(cls, initstr)
return s
def __init__(self, initstr, **kwargs):
d = {}
for name in _findkeys(self):
d[name] = kwargs.get(name, None)
self.__dict__["_attribs"] = d
def __setattr__(self, name, val):
if name not in self.__dict__["_attribs"].keys():
raise AttributeError, "invalid attribute name %r" % (name,)
self.__dict__["_attribs"][name] = val
def __getattr__(self, name):
try:
return self.__dict__["_attribs"][name]
except KeyError:
raise AttributeError, "Invalid attribute %r" % (name,)
def __str__(self):
if None in self._attribs.values():
raise ValueError, "one of the attributes %r is not set" %
(self._attribs.keys(),)
return self % self._attribs
def __call__(self, **kwargs):
for name, value in kwargs.items():
setattr(self, name, value)
return self % self._attribs
def __repr__(self):
return "%s(%s)" % (self.__class__.__name__, str.__repr__(self))
def attributes(self):
return self._attribs.keys()

import re
_findkeys = re.compile(r"%\((\w+)\)").findall
del re

-----------

You use it like this:

TEST = mapstr("some%(one)s one\nsome%(two)s three\nsome%(three)s four")
print TEST.attributes()
TEST.one = "one"
TEST.two = "thing"
TEST.three = "where"
print TEST
s = str(TEST) # makes new, substituted, string
assert s == "someone one\nsomething three\nsomewhere four"

This allows you to use mapping-substitution syntax on a special string
object. But the substituted variables are attributes of the object.
String-ifying it gets the new string with the substitutions made.

--
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~
Keith Dart <kd***@kdart.com>
public key: ID: F3D288E4
================================================== ===================
Jul 18 '05 #23

P: n/a
Fredrik Lundh wrote:
Jim Hill wrote:

I'm trying to write a script that writes a script for a rather specialized
task. I know that seems weird, but the original version was written in
Korn shell and most of my team are familiar with the way it does things
even though they don't read Korn.

so why didn't you tell us? ;-)

if you want $-style interpolation, you can use the new string.Template
class (mentioned in passing by Nick above); useful examples here:

http://aspn.activestate.com/ASPN/Coo.../Recipe/304004

if you don't have 2.4, you can use the RE machinery for the same purpose;
see e.g.

http://effbot.org/zone/re-sub.htm#simple-templating


You might also try the following:

---------python--------------
# a self-substituting string object. Just set attribute names to mapping
names
# that are given in the initializer string.
class mapstr(str):
def __new__(cls, initstr, **kwargs):
s = str.__new__(cls, initstr)
return s
def __init__(self, initstr, **kwargs):
d = {}
for name in _findkeys(self):
d[name] = kwargs.get(name, None)
self.__dict__["_attribs"] = d
def __setattr__(self, name, val):
if name not in self.__dict__["_attribs"].keys():
raise AttributeError, "invalid attribute name %r" % (name,)
self.__dict__["_attribs"][name] = val
def __getattr__(self, name):
try:
return self.__dict__["_attribs"][name]
except KeyError:
raise AttributeError, "Invalid attribute %r" % (name,)
def __str__(self):
if None in self._attribs.values():
raise ValueError, "one of the attributes %r is not set" %
(self._attribs.keys(),)
return self % self._attribs
def __call__(self, **kwargs):
for name, value in kwargs.items():
setattr(self, name, value)
return self % self._attribs
def __repr__(self):
return "%s(%s)" % (self.__class__.__name__, str.__repr__(self))
def attributes(self):
return self._attribs.keys()

import re
_findkeys = re.compile(r"%\((\w+)\)").findall
del re

-----------

You use it like this:

TEST = mapstr("some%(one)s one\nsome%(two)s three\nsome%(three)s four")
print TEST.attributes()
TEST.one = "one"
TEST.two = "thing"
TEST.three = "where"
print TEST
s = str(TEST) # makes new, substituted, string
assert s == "someone one\nsomething three\nsomewhere four"

This allows you to use mapping-substitution syntax on a special string
object. But the substituted variables are attributes of the object.
String-ifying it gets the new string with the substitutions made.

--
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~
Keith Dart <kd***@kdart.com>
public key: ID: F3D288E4
================================================== ===================
Jul 18 '05 #24

P: n/a
Jim Hill wrote:
Fredrik Lundh wrote:
Scott David Daniels wrote:

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(quote)
source[1::2] = (str(eval(expr, d, locals or d)) [fixing the !#@!$ tab that snuck in there] for expr in source[1::2])
return ''.join(source)


And if you prefer not to type so much:

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

Not that I don't appreciate the suggestions from masters of the Python
universe, but the reason I'm switching to Python from Perl is for the
readability. What you fells are suggesting might as well be riddled
with dollar signs and semicolons... <emoticon>.

Really what I was trying to showing you was that you could use eval and
do arbitrary expressions using sneaky slicing.

v[1::2] is every odd position, and it can be used for replacement.

v[1::2] = [str(eval(txt)) for txt in v[1::2]]

Is likely what you want; it got ugly when I lifted it into a function.
The cute trick is to use a quote delimiter and observe that the odd
positions are the quoted text.

--Scott David Daniels
Sc***********@Acm.Org
Jul 18 '05 #25

P: n/a
Jim Hill <ji*****@swcp.com> wrote:
Nick Craig-Wood wrote:
I prefer this

... I'll have %(amount)s %(what)s
... for $%(cost)s please""" % locals()


Looks pretty slick. This might just be what I need.
Its almost as neat as perl / shell here documents and emacs parses """
strings properly too ;-)


Mmm...emacs...

Thanks for the tip.


You are welcome! I came to python after many years of perl too...

--
Nick Craig-Wood <ni**@craig-wood.com> -- http://www.craig-wood.com/nick
Jul 18 '05 #26

P: n/a
> Jim Hill wrote:
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)


No, it is currently not possible in Python without the hacks you have
seen already. Python is long overdue for simpler string interpolation
as seen in many other scripting languages.

You should add a feature request to have this in Python 3.0, a.k.a.
Python 3000: http://www.python.org/cgi-bin/moinmoin/Python3.0

Then you could simple do something like:

variable1 = 1
variable2 = 2

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

However, Python 3.0 is likely years away. If you want to know how to
run code like this today, consult Fredrik Lundh.
Jul 18 '05 #27

P: n/a
On Mon, 20 Dec 2004 18:58:09 -0600, Doug Holton <in****@spam.here> wrote:
Jim Hill wrote:
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)
No, it is currently not possible in Python without the hacks you have
seen already. Python is long overdue for simpler string interpolation
as seen in many other scripting languages.

You should add a feature request to have this in Python 3.0, a.k.a.
Python 3000: http://www.python.org/cgi-bin/moinmoin/Python3.0

Then you could simple do something like:

variable1 = 1
variable2 = 2

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

However, Python 3.0 is likely years away. If you want to know how to
run code like this today, consult Fredrik Lundh.


Or replace ${...} with equally simple %(...)s in the above and be happy ;-)
variable1 = 1
variable2 = 2

s = """ ... v = ${variable1}
... v2's value is: ${variable2}
... """ print s.replace('${','%(').replace('}',')s') % locals()


v = 1
v2's value is: 2

Better would be to write it with %(...)s in the first place though, or you may need
regex help for correct conversion (if involve other uses for the ${} chars).

Regards,
Bengt Richter
Jul 18 '05 #28

P: n/a
Bengt Richter wrote:
variable1 = 1
variable2 = 2

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

However, Python 3.0 is likely years away. If you want to know how to
run code like this today, consult Fredrik Lundh.

Or replace ${...} with equally simple %(...)s in the above and be happy ;-)


I'm afraid you are incorrect. Simply replacing the $ with % in my
example will not work in Python.
If you would like to use % instead of $, I recommend requesting that
feature for Python 3.0: http://www.python.org/cgi-bin/moinmoin/Python3.0
Jul 18 '05 #29

P: n/a
Doug Holton wrote:
Bengt Richter wrote:
variable1 = 1
variable2 = 2

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

However, Python 3.0 is likely years away. If you want to know how to
run code like this today, consult Fredrik Lundh.


Or replace ${...} with equally simple %(...)s in the above and be
happy ;-)

I'm afraid you are incorrect. Simply replacing the $ with % in my
example will not work in Python.
If you would like to use % instead of $, I recommend requesting that
feature for Python 3.0: http://www.python.org/cgi-bin/moinmoin/Python3.0


Oh, but it does work:
variable1 = 1
variable2 = 2
s = """ ... v1 = %(variable1)s
... v2's value is: %(variable2)s
... """ print s % vars()


v1 = 1
v2's value is: 2

--Jim
Jul 18 '05 #30

P: n/a
Doug Holton wrote:
Bengt Richter wrote:
variable1 = 1
variable2 = 2

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

However, Python 3.0 is likely years away. If you want to know how to
run code like this today, consult Fredrik Lundh.


Or replace ${...} with equally simple %(...)s in the above and be
happy ;-)

I'm afraid you are incorrect. Simply replacing the $ with % in my
example will not work in Python.
If you would like to use % instead of $, I recommend requesting that
feature for Python 3.0: http://www.python.org/cgi-bin/moinmoin/Python3.0


Or use boo - it's probably in there already ;-)

must-stop-baiting-the-holton-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
Jul 18 '05 #31

P: n/a
Steve Holden wrote:
If you would like to use % instead of $, I recommend requesting that feature for Python 3.0:
http://www.python.org/cgi-bin/moinmoin/Python3.0


Or use boo - it's probably in there already ;-)


weren't you supposed to ask me about it?

</F>

Jul 18 '05 #32

P: n/a
Fredrik Lundh wrote:
Steve Holden wrote:

If you would like to use % instead of $, I recommend requesting that feature for Python 3.0:
http://www.python.org/cgi-bin/moinmoin/Python3.0


Or use boo - it's probably in there already ;-)

weren't you supposed to ask me about it?

</F>


Aah, right, sorry about that. I understand you are the world's expert on
writing advanced solutions in which you have a financial interest
without using features only available in Python 3.0.

Would you care to comment on why you wouldn't say "boo" to a goose, and
whether the easierInBoo() decorator will be implemented in Imaging 1.2?

must-stop-going-for-the-low-hanging-fruit-ly y'rs - steve

PS: If Doug Holton will just laugh at himself, even once, I promise to
stop this nonsense immediately. There's always other nonsense to replace it.
--
Steve Holden http://www.holdenweb.com/
Python Web Programming http://pydish.holdenweb.com/
Holden Web LLC +1 703 861 4237 +1 800 494 3119
Jul 18 '05 #33

P: n/a
Fredrik Lundh wrote:
Jim Hill wrote:
I'm trying to write a script that writes a script for a rather specialized
task. I know that seems weird, but the original version was written in
Korn shell and most of my team are familiar with the way it does things
even though they don't read Korn.


so why didn't you tell us? ;-)


I was afraid there'd be mockery involved and not originating on my end.
Jim, delicately sensitive to mockery despite burly masculinity
--
"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
Jul 18 '05 #34

This discussion thread is closed

Replies have been disabled for this discussion.