Marcel Tesch
Marcel Tesch

Reputation: 152

operators as classmethod in python 2 vs. 3

I understand that you can overload operators as classmethods using metaclasses:

class _Two(type):
    def __add__(self, other):
        return (2 + other)

class Two(object):
    __metaclass__ = _Two

Two + 3 # 5

It works in Python 2.7.6 but fails in 3.4.0 with this error:

TypeError: unsupported operand type(s) for +: 'type' and 'int'

Why is that?

You could do it in a way compatible with both versions like this however:

class _Two(type):
    def __add__(self, other):
        return (2 + other)

class Two(_Two('', (object,), {})): pass

Two + 3 # 5

I get why the second version works but to my eye it's doing essentially the same as the first one, so what am I missing?

Upvotes: 2

Views: 105

Answers (1)

jme
jme

Reputation: 20755

The correct way of using metaclasses in Python3 is:

class Two(metaclass=_Two):
    ...

That is, there's nothing special about adding __metaclass__ as a class attribute in Python3. You're getting the same error as you'd see if you wrote:

>>> class Two(object):
        this_does_nothing_special = _Two
>>> Two + 3
TypeError: unsupported operand type(s) for +: 'type' and 'int'

Upvotes: 3

Related Questions