简体   繁体   中英

How to apply __add__ method to an infinite count of class instances?

For example I have a class and by using __add__ method on it's instances I want to add their salaries.

class Employee():
    def __init__(self,salary):
        self.salary = salary

    def __add__(self,other):
        return self.salary + other.salary

emp_1 = Employee(4000)
emp_2 = Employee(5000)
emp_3 = Employee(8000)

It does not work with 3 or more arguments: print(emp_1 + emp_2 + emp_3) outputs TypeError: unsupported operand type(s) for +: 'int' and 'Employee' . How can more than 2 instances be added up?

What you can do, if you insist on continuing with this awful, terrible, no-good idea, is write your __add__ method so it knows how to add both integers and Employee instances to itself, and also define __radd__ so that when the left item is an integer, your class still gets a chance to do the addition.

Since addition of numbers is commutative, __radd__ can just be the same as __add__ .

class Employee():

    def __init__(self, salary):
        self.salary = salary

    def __add__(self, other):
        if isinstance(other, Employee):
            other = other.salary
        return self.salary + other

    __radd__ = __add__

If you want to support any other object that has a salary attribute, not just instances of your Employee class, you can write __add__ like:

def __add__(self, other):
    # get other.salary if it exists, otherwise just use other
    return self.salary + getattr(other, "salary", other)

This is how it can be done, but I want to re-re-emphasize that this is a bad idea. It doesn't make sense to add employees. What happens when you add age or gender in here? What gender would the temporary Employee instance have?

class Employee():
    def __init__(self,salary):
        self.salary = salary

    def __add__(self,other):
        return Employee(self.salary + other.salary)

    def __repr__(self):
        return f"${self.salary}"

emp_1 = Employee(4000)
emp_2 = Employee(5000)
emp_3 = Employee(8000)
print( emp_1 + emp_2 + emp_3 )

Output:

$17000

FOLLOWUP

Here's another way, based on sj95126's comment. Here, the addition returns an integer, and we add an add override that can add itself to a simple integer. This doesn't use the __repr__ method.

class Employee():
    def __init__(self,salary):
        self.salary = salary

    def __radd__(self,other):
        return self.salary + other

    def __add__(self,other):
        return self.salary + other.salary

    def __repr__(self):
        return f"${self.salary}"

emp_1 = Employee(4000)
emp_2 = Employee(5000)
emp_3 = Employee(8000)
print( emp_1 + emp_2 + emp_3 )

Output:

17000

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM