Easy "here documents" ??

F

Fredrik Lundh

Jim said:
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>
 
F

Fredrik Lundh

Jim said:
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/Cookbook/Python/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>
 
K

Keith Dart

Fredrik said:
Jim Hill wrote:




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/Cookbook/Python/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.
 
K

Keith Dart

Fredrik said:
Jim Hill wrote:




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/Cookbook/Python/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.
 
S

Scott David Daniels

Jim said:
Fredrik said:
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
(e-mail address removed)
 
N

Nick Craig-Wood

Jim Hill said:
Looks pretty slick. This might just be what I need.


Mmm...emacs...

Thanks for the tip.

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

Doug Holton

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.
 
B

Bengt Richter

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 ;-)
... v = ${variable1}
... v2's value is: ${variable2}
... """
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
 
S

Steve Holden

Fredrik said:
Steve Holden wrote:




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.
 
J

Jim Hill

Fredrik said:
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,763
Messages
2,569,563
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top