Переопределение __add__, исключение не перехватывается при попытке super().__add__

Я пытаюсь создать подкласс панд Timedelta, поэтому, когда он суммируется целым числом/плавающим числом, мы рассматриваем его как Timedelta с секундами.

Я пробовал следующее:

class Timedelta(pd.Timedelta):
    def __add__(self, other):
        print("OVERRIDEN ADD")
        try:
            print("SUPER ADD")
            return super().__add__(other)
        except:
            print("NEW ADD")
            return super().__add__(Timedelta(str(other)+"s"))

Но по какой-то причине я не могу заставить его перейти к реализации "NEW ADD":

>>> a = Timedelta2('10s')
>>> a+1
OVERRIDEN ADD
Traceback (most recent call last):
  File "C:\Python36\lib\site-packages\IPython\core\interactiveshell.py", line 2910, in run_code
SUPER ADD
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-51-98b939904c8e>", line 1, in <module>
    a+1
TypeError: unsupported operand type(s) for +: 'Timedelta2' and 'int'

Я ожидал, что это исключение TypeError будет перехвачено, но по какой-то причине это не так, поэтому я хотел бы попросить помощи, чтобы выяснить, что здесь может происходить.

Спасибо!


person SuperGeo    schedule 26.01.2018    source источник


Ответы (2)


super().__add__(other) не вызывает исключения! Он возвращает NotImplemented. Вот как вы сигнализируете, что ваша перегрузка оператора не понимает аргумент, который она получает. TypeError исходит от машин оператора, как только обе стороны говорят, что не могут выполнить операцию.

Вместо того, чтобы пытаться поймать исключение, которое все равно не исходит оттуда, проверьте, возвращает ли super().__add__(other) NotImplemented.

person user2357112 supports Monica    schedule 26.01.2018

Вы не совсем понимаете метод __add__! попробуйте ниже способ получить ваши ожидания! try ... expect неэффективен, поэтому вместо него следует использовать if .. else.

import pandas as pd

class MyTimedelta(pd.Timedelta):
    def __add__(self, other):
        print("OVERRIDEN ADD")
        if isinstance(other, int):
            return pd.Timedelta("{}s".format(int(self.seconds)+ other))
        else:    
            super(MyTimedelta, self).__add__(other)

а затем вы можете выполнить операцию следующим образом:

In [22]: s=MyTimedelta('2s')

In [23]: s+3
OVERRIDEN ADD
Out[23]: Timedelta('0 days 00:00:05')
person Frank AK    schedule 26.01.2018
comment
Что значит try ... except неэффективно? Это намного эффективнее, чем каждый раз проверять тип значения. Попробуйте это. - person Jose A.; 26.01.2018