Skip to content Skip to sidebar Skip to footer

Replacing __str__ In New-style Class

I'm converting old Python code and replaced some classes with new style classes. The problem is that this broke the behavior of replacing __str__ and I have no idea why. class OldS

Solution 1:

This is documented in the python Data model under special method names. Specifically:

For instance, if a class defines a method named __getitem__, and x is an instance of this class, then x[i] is roughly equivalent to x.__getitem__(i) for old-style classes and type(x).__getitem__(x, i) for new-style classes.

I believe that this allows new-style classes to be a little more efficient in terms of these operations because with the old style classes, python was forced to look up the attribute and then call the attribute, with new-style classes, python can just reference it as part of a C struct somewhere effectively pushing the lookups and calls into native C code. For example:

classFoo:
    def__add__(self,other):
        return4 + other

classBar(object):
    def__add__(self,other):
        return4 + other

import timeit
print timeit.timeit('f + 5','from __main__ import Foo; f = Foo()')
print timeit.timeit('b + 5','from __main__ import Bar; b = Bar()')

For me (python2.7.3, OS-X 10.5.8), the new-style class is almost 4 times faster!

2.27801704407
0.602614879608

Solution 2:

This works:

NewStyle.__str__ = lambda self: 'modified'

It seems like what we're seeing is that the __str__ method is tied to the class type now, rather than the instance. I'm not sure why that is. You can call new.__str__() explicitly and get the replaced method, but str(new) always calls NewStyle.__str__(new).

Post a Comment for "Replacing __str__ In New-style Class"