Videos
I think it's just an (undocumented) artifact from the way set.itersection(*others) is implemented and therefore should apply to any other classes with methods that support a variable number of other objects.
To illustrate and prove my point, here's a custom class that supports this so-called "functional notation" via its own intersection() method.
Copyclass Class:
def __init__(self, value=''):
self.value = str(value)
self.type = type(value)
pass
def __repr__(self):
return f'Class({self.type(self.value)!r})'
def intersection(self, *others):
result = self
for other in others:
result &= other # Perform via __and__() method.
return result
def __and__(self, other):
return type(self)('|'.join((self.value, other.value)))
c1 = Class('foo')
c2 = Class('bar')
c3 = Class(42)
print(f'c1: {c1}')
print(f'c2: {c2}')
print(f'c3: {c3}')
# Both produce the same result.
print(c1 & c2 & c3)
print(Class.intersection(c1, c2, c3))
Output
c1: Class('foo')
c2: Class('bar')
c3: Class(42)
Class('foo|bar|42')
Class('foo|bar|42')
In addition to martineau answer, a method called through a class instance like obj1.method1(...) can also be called with obj1_class.method1(obj1, ...), and in the C implementation code I only see the assumption of the first argument to be a set. That is what happens too when you unpack others, this being a list of sets.
Maybe it is undocumented in the method help, but should be expected anyway.
So I also agree with
and therefore should apply to any other classes with methods that support a variable number of other objects.