Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
322 views
in Technique[技术] by (71.8m points)

python - How to properly overload the __add__ method?

I am required to write a class involving dates. I am supposed to overload the + operator to allow days being added to dates. To explain how it works: A Date object is represented as (2016, 4, 15) in the format (year, month, date). Adding integer 10 to this should yield (2016, 4, 25). The Date class has values self.year, self.month, self.day.

My problem is that the code is supposed to work in the form Date + 10 as well as 10 + Date. Also Date - 1 should work in the sense of adding a negative number of days. Date(2016, 4, 25) - 1 returns Date(2016, 4, 24).

My code works perfectly in the form of Date + 10 but not in the form 10 + D or D - 1.

def __add__(self,value):
    if type(self) != int and type(self) != Date or (type(value) != int and type(value) != Date):
        raise TypeError
    if type(self) == Date:
        day = self.day
        month = self.month
        year = self.year
        value = value
    if type(value) != int:
        raise TypeError
    days_to_add = value
    while days_to_add > 0:
        day+=1
        if day == Date.days_in(year,month):
            month+=1
            if month > 12:
                day = 0
                month = 1
                year+=1
            day = 0
        days_to_add -=1
    return(Date(year,month,day))

These are the errors I get

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

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

__radd__ handles right side addition so you need to implement that as well.

I am seeing some flaws in your implementation so I recommend you using datetime module (especially datetime.timedelta class) to at least handle basic date arithmetic correctly:

import datetime

class Date(object):
    def __init__(self, year, month, day):
        self.year = year
        self.month = month
        self.day = day

    def as_date(self):
        return datetime.date(self.year, self.month, self.day)

    def __add__(self, other):
        if isinstance(other, int):
            date = self.as_date() + datetime.timedelta(days=other)
            return Date(date.year, date.month, date.day)
        else:
            raise ValueError("int value is required")

    def __radd__(self, other):
        return self.__add__(other)

    def __sub__(self, other):
        return self.__add__(-other)

    def __rsub__(self, other):
        raise RuntimeError("Doesn't make sense.")

    def __repr__(self):
        return str(self.as_date())

Demo:

>>> date = Date(2015, 10, 23)
>>> print date + 10 # __add__ is called
2015-11-02

>>> print 20 + date # __radd__ is called
2015-11-12

>>> print date - 25 # __sub__ is called
2015-09-28

>>> print 25 - date # __rsub__ is called 
RuntimeError: Doesn't make sense

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...