Inelegant

Bengt Richter bokr at oz.net
Thu Apr 14 06:05:43 EDT 2005


On Thu, 14 Apr 2005 02:43:40 -0500, Terry Hancock <hancock at anansispaceworks.com> wrote:

>On Thursday 14 April 2005 02:03 am, Dan wrote:
>> If you use triple quotes to define a string, then the newlines are
>> implicitly included.  This is a very nice feature.  But if you're
>> inside a function or statement, then you'll want the string to be
>> positioned along that indentation.  And the consequences of this is
>> that the string will include those indentations.
>>  [...]
>> But that's just ugly. 
>
>Yeah, it's definitely a wart.  So much so that recent Python
>distributions include a function to fix it:
>
>>>> from textwrap import dedent
>>>> string_block = dedent("""
>...                       This string will have the leading
>...                       spaces removed so that it doesn't
>...                       have to break up the indenting.
>...                       """)
>>>> string_block
>"\nThis string will have the leading\nspaces removed so that it doesn't\nhave to break up the indenting.\n"
>>>> print string_block
> 
>This string will have the leading
>spaces removed so that it doesn't
>have to break up the indenting.
> 

I never liked any of the solutions that demand bracketing the string with expression brackets,
but I just had an idea ;-)

 >>> class Dedent(object):
 ...     def __init__(self, **kw): self.kw = kw
 ...     def __add__(self, s):
 ...         lines = s.splitlines()[1:]
 ...         margin = self.kw.get('margin', 0)*' '
 ...         mnow = min(len(L)-len(L.lstrip()) for L in lines)
 ...         return '\n'.join([line[mnow:] and margin+line[mnow:] or '' for line in lines])
 ...
 ...

Normally you wouldn't pass **kw in like this,
you'd just write
         mystring = Dedent()+\

or

         mystring = Dedent(margin=3)+\

but  I wanted to control the print. Note the the first line, unless you escape it (ugly there)
is zero length and therefore has zero margin, which subverts the other shifting, so I just drop that line.
You have to live with the backslash after the + as payment for preferring not to have parentheses ;-)

 >>> def foo(**kw):
 ...     mystring = Dedent(**kw)+\
 ...     """
 ...     This makes
 ...        for a cleaner isolation
 ...     of the string IMO.
 ...     """
 ...     return mystring
 ...
 >>> print '----\n%s----'%foo()
 ----
 This makes
    for a cleaner isolation
 of the string IMO.
 ----
 >>> print '----\n%s----'%foo(margin=3)
 ----
    This makes
       for a cleaner isolation
    of the string IMO.
 ----

Regards,
Bengt Richter



More information about the Python-list mailing list