Help | Site Map
Connecting Tech Pros Worldwide
 
 
LinkBack Thread Tools
  #1  
Old July 19th, 2005, 12:59 AM
Dan
Guest
 
Posts: n/a
Default Inelegant


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
  #2  
Old July 19th, 2005, 12:59 AM
Terry Hancock
Guest
 
Posts: n/a
Default Re: Inelegant

On Thursday 14 April 2005 02:03 am, Dan wrote:[color=blue]
> 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.[/color]

Yeah, it's definitely a wart. So much so that recent Python
distributions include a function to fix it:
[color=blue][color=green][color=darkred]
>>> from textwrap import dedent
>>> string_block = dedent("""[/color][/color][/color]
.... This string will have the leading
.... spaces removed so that it doesn't
.... have to break up the indenting.
.... """)[color=blue][color=green][color=darkred]
>>> string_block[/color][/color][/color]
"\nThis string will have the leading\nspaces removed so that it doesn't\nhave to break up the indenting.\n"[color=blue][color=green][color=darkred]
>>> print string_block[/color][/color][/color]

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

  #3  
Old July 19th, 2005, 12:59 AM
Bengt Richter
Guest
 
Posts: n/a
Default Re: Inelegant

On Thu, 14 Apr 2005 02:43:40 -0500, Terry Hancock <hancock@anansispaceworks.com> wrote:
[color=blue]
>On Thursday 14 April 2005 02:03 am, Dan wrote:[color=green]
>> 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.[/color]
>
>Yeah, it's definitely a wart. So much so that recent Python
>distributions include a function to fix it:
>[color=green][color=darkred]
>>>> from textwrap import dedent
>>>> string_block = dedent("""[/color][/color]
>... This string will have the leading
>... spaces removed so that it doesn't
>... have to break up the indenting.
>... """)[color=green][color=darkred]
>>>> string_block[/color][/color]
>"\nThis string will have the leading\nspaces removed so that it doesn't\nhave to break up the indenting.\n"[color=green][color=darkred]
>>>> print string_block[/color][/color]
>
>This string will have the leading
>spaces removed so that it doesn't
>have to break up the indenting.
>[/color]

I never liked any of the solutions that demand bracketing the string with expression brackets,
but I just had an idea ;-)
[color=blue][color=green][color=darkred]
>>> class Dedent(object):[/color][/color][/color]
... 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 ;-)
[color=blue][color=green][color=darkred]
>>> def foo(**kw):[/color][/color][/color]
... mystring = Dedent(**kw)+\
... """
... This makes
... for a cleaner isolation
... of the string IMO.
... """
... return mystring
...[color=blue][color=green][color=darkred]
>>> print '----\n%s----'%foo()[/color][/color][/color]
----
This makes
for a cleaner isolation
of the string IMO.
----[color=blue][color=green][color=darkred]
>>> print '----\n%s----'%foo(margin=3)[/color][/color][/color]
----
This makes
for a cleaner isolation
of the string IMO.
----

Regards,
Bengt Richter
  #4  
Old July 19th, 2005, 12:59 AM
gry@ll.mit.edu
Guest
 
Posts: n/a
Default Re: Inelegant

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

  #5  
Old July 19th, 2005, 01:09 AM
Greg Ewing
Guest
 
Posts: n/a
Default Re: Inelegant

Bengt Richter wrote:
[color=blue]
> I never liked any of the solutions that demand bracketing the string with expression brackets,
> but I just had an idea ;-)[/color]

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
 

Bookmarks

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are Off
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

What is Bytes?

We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights. Get the best answers to your questions from over network members.
Post your question now . . .
It's fast and it's free

Popular Articles