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

Inelegant

P: n/a
Dan

I've just begun playing with Python, and so far I like what I see.
It's a very elegant language. But I've found something that's, well,
a bit ugly. Maybe someone can point out to me where I'm wrong.

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.

For example:

def SomeFunction()
if SomeCondition:
MyString =
"""
The quick brown fox
"""
print MyString

The output will be:

The quick brown fox

But what you really want is:

The quick brown fox

The way around it is to write the function thus:

def SomeFunction()
if SomeCondition:
MyString =
"""
The quick brown fox
"""
print MyString

But that's just ugly. It seems to me that the string should be
interpreted with the edge along the indentation line, not from the
start of the line. But that would probably create other problems.

Dan
Jul 18 '05 #1
Share this Question
Share on Google+
4 Replies


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


--
Terry Hancock ( hancock at anansispaceworks.com )
Anansi Spaceworks http://www.anansispaceworks.com

Jul 18 '05 #2

P: n/a
On Thu, 14 Apr 2005 02:43:40 -0500, Terry Hancock <ha*****@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
Jul 18 '05 #3

P: n/a
gry
I sometimes use the implicit literal string concatenation:

def SomeFunction():
if SomeCondition:
MyString = 'The quick brown fox ' \
'jumped over the ' \
'lazy dog'
print MyString

SomeFunction()
The quick brown fox jumped over the lazy dog
It looks pretty good, I think. One could use triple quotes too, if the
string
contains quotes.

-- George

Jul 18 '05 #4

P: n/a
Bengt Richter wrote:
I never liked any of the solutions that demand bracketing the string with expression brackets,
but I just had an idea ;-)


Or for an even more twisted idea:
from textwrap import dedent

class _Dedent(type):

def __new__(cls, name, bases, dict):
if name == "*": # for bootstrapping
return type.__new__(cls, name, bases, dict)
return dedent(dict['__doc__'])

DedentedString = _Dedent("*", (), {})

#
# Usage example
#

class foo(DedentedString):
"""
This is a dedented (or perhaps demented?) string.
It spans multiple lines.
"""

print type(foo)
print foo

The output is:

<type 'str'>

This is a dedented (or perhaps demented?) string.
It spans multiple lines.
--
Greg Ewing, Computer Science Dept,
University of Canterbury,
Christchurch, New Zealand
http://www.cosc.canterbury.ac.nz/~greg
Jul 19 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.