-2

python 3.7.0

in the following code

a+a and a.__add__(a) could be different

how can I let a+a return a.__add__(a)?

import tensorflow as tf

class T(tf.Tensor):
    def __init__(self, data):
        super().__init__(data.op, data.value_index, data.dtype)
        def res(self, arg):
            print("ADD")
            return super().__add__(arg)
        setattr(self,"__add__",res.__get__(self,T))

a = T(tf.constant([1,2,3]))

a+a
print("--- a line ---")
a.__add__(a)

run it and get

--- a line ---
ADD

because I want to reload several builtin function with the similar rules

I want to use a loop to realize.

so defining function directly in class such as

class lalala():
    def __add__(self,args):
        return blabla

not works for me


BTW, I found metaclass works

import tensorflow as tf

class MetaT(type):
    def __new__(cls, n, b, a):
        def res(self, arg):
            print("ADD")
            return super(self.__class__, self).__add__(arg)
        a["__add__"] = res
        return type.__new__(cls, n, b, a)

class T(tf.Tensor, metaclass=MetaT):
    def __init__(self, D):
        super().__init__(D.op, D.value_index, D.dtype)

a = T(tf.constant([1,2,3]))

b = a+a
print("--- a line ---")
b = type(a).__add__(a,a)

this output:

ADD
--- a line ---
ADD
Hao Zhang
  • 49
  • 2

1 Answers1

0

Dunder methods for operation overriding are called from the class, not its instances. Here you overwrite a.__add__ instead of T.__add__.

You need to declare __add__ in the class body.

class T(tf.Tensor):
    def __init__(self, data):
        super().__init__(data.op, data.value_index, data.dtype)

    def __add__(self, arg):
        print("ADD")
        return super().__add__(arg)

a = T(tf.constant([1,2,3]))

a+a # prints: ADD
Olivier Melançon
  • 21,584
  • 4
  • 41
  • 73