0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

About __str__ and __unicode__ (and six.python_2_unicode_compatible)

Posted at

Let's define a class like this:

class K(object):
    def __str__(self):
        return u'str'
    def __unicode__(self):
        return 'unicode'

print(repr( str(K()) ))
print(repr( unicode(K()) ))

And the result is like this:

'str'
u'unicode'

It is notable that str() converts unicode to str and unicode() converts str to unicode. No errors are raised if different string type is returned.

Now let's define other class:

# copied from https://github.com/benjaminp/six/blob/1.16.0/six.py

import sys
PY2 = sys.version_info[0] == 2
def python_2_unicode_compatible(klass):
    """
    A class decorator that defines __unicode__ and __str__ methods under Python 2.
    Under Python 3 it does nothing.

    To support Python 2 and 3 with a single code base, define a __str__ method
    returning text and apply this decorator to the class.
    """
    if PY2:
        if '__str__' not in klass.__dict__:
            raise ValueError("@python_2_unicode_compatible cannot be applied "
                             "to %s because it doesn't define __str__()." %
                             klass.__name__)
        klass.__unicode__ = klass.__str__
        klass.__str__ = lambda self: self.__unicode__().encode('utf-8')
    return klass

@python_2_unicode_compatible
class S(object):
    def __str__(self):
        return u'str'
    def __unicode__(self):
        return 'unicode'

print(repr( str(S()) ))
print(repr( unicode(S()) ))

And the result is like this:

'str'
u'str'

Now take a deeper look at python_2_unicode_compatible implementation, it is doing two things:

  1. (checks if py2)
  2. copy __str__ to __unicode__
  3. set __str__ to unicode(self).encode('utf-8')

So (along with wrapping with python_2_unicode_compatible) the correct way to implement __str__ is to return u-string.

cf: https://wandbox.org/permlink/xHIO4C7HIk2J2kZL

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?