Vorac
Vorac

Reputation: 9114

Can some operators in Python not be overloaded properly?

I am studying Scott Meyers' More Effective C++. Item 7 advises to never overload && and ||, because their short-circuit behavior cannot be replicated when the operators are turned into function calls (or is this no longer the case?).

As operators can also be overloaded in Python, I am curious whether this situation exists there as well. Is there any operator in Python (2.x, 3.x) that, when overridden, cannot be given its original meaning?

Here is an example of 'original meaning'

class MyInt {
    public: 
    MyInt operator+(MyInt &m) {
           return MyInt(this.val + m.val);
    };
    int val; 
    MyInt(int v) : val(v){} 
    }

Upvotes: 2

Views: 172

Answers (3)

Joren Boulanger
Joren Boulanger

Reputation: 136

The assignment operator can also not be overloaded.

class Thing: ...

thing = Thing()
thing = 'something else'

There is nothing you can override in Thing to change the behavior of the = operator.

(You can overload property assignment though.)

Upvotes: 1

jsbueno
jsbueno

Reputation: 110516

In Python, all object methods that represent operators are treated "equal": their precedences are described in the language model, and there is no conflict with overriding any.

But both C++ "&&" and "||" - in Python "and" and "or" - are not available in Python as object methods to start with - they check for the object truthfulness, though - which is defined by __bool__. If __bool__is not implemented, Python check for a __len__ method, and check if its output is zero, in which case the object's truth value is False. In all other cases its truth value is True. That makes it for any semantic problems that would arise from combining overriding with the short-circuiting behavior.

Note one can override & and | by implementing __and__ and __or__ with no problems.

As for the other operators, although not directly related, one should just take care with __getattribute__ - the method called when retrieving any attribute from an object (we normally don't mention it as an operator) - including calls from within itself. The __getattr__ is also in place, and is just invoked at the end of the attribute search chain, when an attribute is not found.

Upvotes: 0

georg
georg

Reputation: 215019

Exactly the same rationale applies to Python. You shouldn't (and can't) overload and and or, because their short-circuiting behavior cannot be expressed in terms of functions. not isn't permitted either - I guess this is because there's no guarantee that it will be invoked at all.

As pointed out in the comments, the proposal to allow the overloading of logical and and or was officially rejected.

Upvotes: 1

Related Questions