Easy "here documents" ??

Keith Dart kdart at kdart.com
Mon Dec 20 08:38:57 CET 2004

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/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:

# a self-substituting string object. Just set attribute names to mapping 
# 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):
			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" % 
		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 <kdart at kdart.com>
    public key: ID: F3D288E4

More information about the Python-list mailing list