Yosh
Yosh

Reputation: 2742

Python : how to make subclasses 'closed' under methods inherited from its superclass

I know I should have come up with a better title, but anyway...

Say I make a class inherited from int in python:

class Foo(int):

    def is_even(self):
        return self%2 == 0

and do something like this

a = Foo(3)
b = Foo(5)
print(type(a+b)) #=> <class 'int'>

I understand this behaviour is not surprising at all, as __add___ called here is defined to return int instances. But I would like to create a class so that a+b returns Foo(8). In other words, I'd like the result a+b to have the is_even method.

Is there any way I can achieve this conveniently? Or do I have to overwrite __add__ and everything?

Background information: I'm trying to write an interpreter for an esoteric programming language called Grass . In that attempt, I want to have a class that behaves like 'callable-int' (actually, numpy.uint8), whose __call__ would be like

def __call__(self, other):
    if self == other:
        return lambda x: lambda y: x
    else:
        return lambda x: lambda y: y

.

Upvotes: 2

Views: 105

Answers (1)

Toote
Toote

Reputation: 3413

There are tricks that you could do with metaclasses (__metaclass__ class variable) or the __getattribute__ special method. But the documentation states:

Bypassing the getattribute() machinery in this fashion provides significant scope for speed optimisations within the interpreter, at the cost of some flexibility in the handling of special methods (the special method must be set on the class object itself in order to be consistently invoked by the interpreter)

Which means that if you want to make sure that the parent class is never handled directly, you need to intercept everything. And for int, that is described as emulating numeric types (i.e.: implementing all those methods).


That said, I believe you could implement all those methods in your class quite easily by creating a lambda or generic method that takes two parameters and just calls super on them. And then assign that method to all the specific methods that you need to implement. So you implement once and reuse it.

Upvotes: 1

Related Questions