Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does the operator += return in Python

Original Question

While I was trying to answer another person's question on stackoverflow about the difference between = and += in Python, I encountered the following problem:

class Foo:
    def __init__(self, value, name="default"):
        self.value = value
        self.name = name
        
    def __add__(self, that):
        return Foo(self.value + that.value)
    
    def __iadd__(self, that):
        self.value = self.value + that.value
        return self
    
    def __str__(self):
        return "name: {}, value: {:d}".format(self.name, self.value)
    
a = Foo(1, 'alice')
b = Foo(2, 'bob')
print(a+=b)

The last print call was not successful and gave me this:

File "<ipython-input-8-0faa82ba9e4a>", line 3
    print(a+=b)
            ^
SyntaxError: invalid syntax

I don't know why this isn't working. Maybe it has something to do with the keyword argument passing mechanism? I just can't find any resource on this topic, since the overloaded __iadd__ method already returns a Foo object.

************** update ******************

If I change the __iadd__ method like this (just remove the return statement):

...
    def __iadd__(self, that):
        print("__iadd__ was called")
        self.value = self.value + that.value

a = Foo(1, 'alice')
b = Foo(2, 'bob')
a += b
print(a)  # Outputs: None

So, the final return statement in __iadd__ is indeed required. But it does not function as I thought (I come from a C/C++ background, so this behavior is a bit strange for me)

************************* 2nd Update ********************************

I almost forget that = in Python makes up a statement instead of an expression. The return statement in __iadd__ and my experience with other languages gives me an illusion that += could be used as an expression.

As stated in the Python documentation, __add__ is used to construct a new object. __iadd__ is designed for inplace modifications. But it all depends on the implementation. Although __iadd__ returns a object, this object is somehow "intercepted" by the language and reassigned to the left-hand operator, and, the final effect is, __iadd__ remains a statement, not an expression. Please correct me if I'm wrong. Also, I didn't find any resource confirming that += is a statement.

Summary

  1. A plain code, say a = 1 is an assignment statement. It's not allowed to be used as a function argument. However, keyword argument passing is not restricted by that: print('Hello world', end='') still works.
    • x = x + y is equivalent to x = x.__add__(y),
    • x += y is equivalent to x = x.__iadd__(y), check the doc for more details.
  2. An example:
class Foo:
    def __init__(self, value, name="default"):
        self.value = value
        self.name = name

    def __add__(self, that):
        return Foo(self.value + that.value)

    def __iadd__(self, that):
        self.value = self.value + that.value
        return self

    def __str__(self):
        return "name: {}, value: {:d}".format(self.name, self.value)

a = Foo(1, 'alice')
b = Foo(2, 'bob')
c = a + b # objects a and b are unchanged
a += b    # object a is changed
print(c) # name: default, value: 3
print(a) # name: alice, value: 3
like image 278
Shihao Xu Avatar asked Feb 25 '21 17:02

Shihao Xu


People also ask

What does operator return in Python?

Python's or operator returns the first Truth-y value, or the last value, and stops. This is very useful for common programming assignments that need fallback values. This will print my_list , if it has anything in it. Otherwise, it will print no values (if list is empty, or it is None ...).

What does and operator return?

The AND operator is represented with two ampersands && : result = a && b; In classical programming, AND returns true if both operands are truthy and false otherwise: alert( true && true ); // true alert( false && true ); // false alert( true && false ); // false alert( false && false ); // false.

What does \\ mean in Python?

In Python strings, the backslash "\" is a special character, also called the "escape" character. It is used in representing certain whitespace characters: "\t" is a tab, "\n" is a newline, and "\r" is a carriage return.

What is the operator Python?

What is Python Operator? Python operator is a symbol that performs an operation on one or more operands. An operand is a variable or a value on which we perform the operation.


1 Answers

Assignments/in-place operations can't be considered as expressions that can be passed on, and that's by design.

Among other things, Guido wanted to avoid the infamous C typo

if (a=b)  // user actually wanted to test a==b

But python 3.8 provides a new assignment method known as assignment expression that allows to pass the assigned value as a parameter (which is very handy in list comprehensions).

You still cannot do in-place add but you can do add then assign:

>> a=2
>> b=3
>> print(a:=a+b)
5
like image 71
Jean-François Fabre Avatar answered Sep 16 '22 15:09

Jean-François Fabre