Practical Use of Reversed Set Operators in Python
Asked Answered
T

2

8

Is there any difference between using the reversed union or intersection operators on sets in Python?

for instance,

s & z corresponds to s.__and__(z)

z & s corresponds to s.__rand__(z)

If these are supposed to return the same thing, why have the reversed operator in the first place? Am I missing something?

Tuxedo answered 4/4, 2017 at 2:17 Comment(1)
It's for when the left-side object doesn't implement the __and__ method.Internship
M
3

set and frozenset follow the number protocol and they don't define the reversed operations explicitly but they get these "for free" because they implement the normal methods (like __and__).

However reversed operations are particularly useful when dealing with subclasses because if the right operand is a subclass of the left operand the reversed operation is attempted first. But in case of plain sets and frozensets this doesn't make any difference because they don't inherit from each other.

These reversed operations are also used if the first operand returns NotImplemented in it's __add__. But again this isn't really useful for set and frozenset because they only allow operations with other set-alikes and at least set and frozenset don't return NotImplemented when the other operand is another set.

Also z & s doesn't correspond to s.__rand__(z), except when s is a subclass of z. Otherwise z.__and__(s) will be attempted before s.__rand__(z).

So I doubt there are use-cases for the reversed union and intersection but it should explain "why these methods exist".

Modifier answered 4/4, 2017 at 2:39 Comment(2)
Are you saying that if I make custom classes that inherit from set or frozenset, and these classes have different __and__ methods, then one needs to watch for the order and what the __rand__ methods contain as well?Tuxedo
Indeed with set and frozenset you need to be careful about the order when you subclass one and try to operate with the other. If you subclass set and implement __and__ and __rand__ your subclasses methods will be called first when you try to do set() & subclass() (=> subclass.__rand__ is called first) or subclass() & set() (=> subclass.__and__ is called first). But if you try to use this subclass with frozenset you need to watch out for the order: frozenset() & subclass() will call frozenset.__and__ first!Modifier
W
0

__rand__ is only called if if the left operand does not support the corresponding operation and the operands are of different types.

I would imagine that s.__rand__(z) would just call z.__and__(s) under the covers.

Wonted answered 4/4, 2017 at 2:32 Comment(1)
Since the operation is invalid except between two sets, the other argument is guaranteed to have the correct method or else there's an error and the rand method doesn't need to be the one that produces it.Extradite

© 2022 - 2024 — McMap. All rights reserved.