views:

67

answers:

3

Firstly, is there one?

If not, is there a nice way to force something like

print '%s' % obj

to call obj.__unicode__ instead of obj.__str__?

+1  A: 

Just use a unicode format string, rather than having a byte string in that role:

>>> class X(object):
...   def __str__(self): return 'str'
...   def __unicode__(self): return u'unicode'
... 
>>> x = X()
>>> print u'%s' % x
unicode
Alex Martelli
Having `__unicode__` return a bytestring and printing a unicode object make awful examples.
Mike Graham
@Mike, agreed on the `return` issue -- fixed that typo. Strong disagreement on the `print`: on a decent platform, `sys.stdout.encoding` is set and the print will work perfectly -- while you're guessing blindly at the `some_encoding` to use (if it's not on sys.stdout how are you gonna guess it, pray?).
Alex Martelli
@Alex, on what "decent platform" does `python -c 'print u"\xff"' >some_file` not raise a UnicodeEncodeError?
Aaron Gallagher
@Aaron, if `sys.stdout.encoding` is `None` (or `'ascii'`, etc), which would be the case in your example, of course printing characters not renderable in that encoding is an error -- just like @Mike's code would be if the mysterious `some_encoding` he uses but never specifies was similarly non-universal (or a mismatch for sys.stdout.encoding, which it completely ignores).
Alex Martelli
A: 

No. It wouldn't make sense for this to be the case.

print (u"%s" % obj).encode(some_encoding) will use obj.__unicode__.

Mike Graham
Hate the idea of blindly guessing at the `some_encoding` as this answer would force one to do -- a decent platform will set `sys.stdout.encoding` so a plain `print` will work perfetly, if yours doesn't you must wrap sys.stdout into a wrapper which sets the encoding, in **one** place (then you can use `print` as is only proper and decent!), rather than strewing such guesses all over the furniture (what a **horrible** way to program).
Alex Martelli
A: 

Firstly, is there one?

Sure (sort of). A unicode format string will convert the format values to unicode, implying that obj.__unicode__ will be called (reference).

u'this is a %s' % ('unicode string')

Aside from the above, there's no particular reason why you couldn't be explicit:

print '%s' % (unicode(obj))
Seth
`print '%s' % unicode(obj)` isn't really explicit. It implicitly upconverts a str into a unicode when the % applies, which is among the uglier things that Python does.
Mike Graham
Stumbled across this a few seconds later. I guess this works for me!
Mark
...and it relies on `print`ing a unicode string exactly like my much reviled, much-downvoted, and much-earlier answer -- seeing this one upvoted instead could confirm suspicion that the downvoters are in fact intent on a personal vendetta, not a technical objection, whatever mealy-mouthed words they may try to dress it up in;-).
Alex Martelli
@Alex: If it's any consolation, I didn't downvote you.
Mark
@Alex - I didn't realize how close my answer was until after I posted it ... you may be right :)
Seth
@Mark, indeed I imagine you didn't, since I see you accepted it -- thanks!-)
Alex Martelli
@Seth, I might -- who knows what purpose lurks in the hearts of men?-)
Alex Martelli