1

Is there any way to define a different function (with the same body) for different version of python?

specifically, for python 2.7 define:

def __unicode__(self): 

and for python 3 define:

def __str__(self):

but both will have the same code / body. both must also be a member of class.

5
  • 1
    Why not always define both and have them make a call to a third function which contains the actual implementation? Commented Apr 13, 2015 at 8:02
  • @deceze because it wouldn't work. Commented Apr 13, 2015 at 9:31
  • @deceze: the interface for __str__ changes between Python 2 and 3. In Python 2, it must return bytes, in Python 3, it must return Unicode. Commented Apr 13, 2015 at 9:34
  • @Martijn Then the "adapter" methods __unicode__ and/or __str__ could do this simple conversion. That's essentially what the answers do. Commented Apr 13, 2015 at 9:37
  • 1
    @deceze __str__ exists in both Python 2 and Python 3, and its return value must be defined differently. Essentially that'd be changing the conditionals that my code executes once per initialization time into once per each invocation, hardly handy anymore. Commented Apr 13, 2015 at 9:59

2 Answers 2

6

While there are compatibility libraries; six and future being the 2 most widely known, sometimes one needs to live without compatibility libs. You can always write your own class decorator, and put it into say mypackage/compat.py. The following works nicely for writing the class in Python 3 format and converting the 3-ready class to Python 2 if needed (the same can be used for next vs __next__, etc:

import sys

if sys.version_info[0] < 3:
    def py2_compat(cls):
        if hasattr(cls, '__str__'):
            cls.__unicode__ = cls.__str__
            del cls.__str__
            # or optionally supply an str that 
            # encodes the output of cls.__unicode__
        return cls
else:
    def py2_compat(cls):
        return cls

@py2_compat
class MyPython3Class(object):
    def __str__(self):
        return u'Here I am!'

(notice that we are using u'' prefix which is PyPy 3, and Python 3.3+ compatible only, so if you need to be compatible with Python 3.2, then you need to adjust accordingly)


To supply a __str__ method that encodes the __unicode__ to UTF-8 in Python 2, you can replace the del cls.__str__ with

def __str__(self):
    return unicode(self).encode('UTF-8')
cls.__str__ = __str__
Sign up to request clarification or add additional context in comments.

Comments

4

The third-party six library defines a python_2_unicode_compatible class decorator which takes a class with a __str__ method and translates it to __unicode__ on Python 2.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.