This is not my idea in the first place, and don't have much use for it. mostly, I was pointing out that adding a couple of the set methods to the Set ABC wouldn't be as disruptive as most additions of methods to ABCs. That's it. But to a couple points:
Why do you want to add them? The point of an ABC is that it is
Abstract. This doesn't just mean "can't instantiate", it also means "only the defining features."
Well, Python's history makes all this a bit backward -- most (all?) of the ABCs existed in concrete form before there wre abstract versions. So it's a bit weird. Maybe if we'd started with ABCs, there would be no "regular" methods at all -- who knows? But anyway, as I understand it, "abstract" means "not implemented", which is completely separate from "only the defining features" -- ABCs define the API, not the feature set. And the fact is that Python has a somewhat arbitrary mix of operators implemented by dunders, protocols implemented by dunders (like the len() function) and regular old methods -- all of these are in the ABCs. So I don't think there's any clear principle here -- do we want .union() and friends to be part of the standard set API or not? It's simply a choice. Judging from some of the arguments in other threads, I suspect some people think that ALL the regular methods are only there for legacy reasons, which might explain why these aren't in the Set ABC -- but I don't know that there's any real consensus about that.
BUT: This *may* be a different case -- the Set ABC (and set
duck-typing) is probably far less used than for Sequences.
I don't know about the Set ABC, but duck-typing is presumably quite common. {1}.union([2]) uses set duck-typing.
no it doesn't -- the set.union method takes any iterable -- that's documented: "Note, the non-operator versions of union() https://docs.python.org/3.8/library/stdtypes.html#frozenset.union, intersection() https://docs.python.org/3.8/library/stdtypes.html#frozenset.intersection, difference() https://docs.python.org/3.8/library/stdtypes.html#frozenset.difference, and symmetric_difference() https://docs.python.org/3.8/library/stdtypes.html#frozenset.symmetric_differ..., issubset() https://docs.python.org/3.8/library/stdtypes.html#frozenset.issubset, and issuperset() https://docs.python.org/3.8/library/stdtypes.html#frozenset.issuperset methods will accept any iterable as an argument." no duck-typing here.
Presumably if self is a set, .union (and .intersection) works on any Sized:
well, not, it doesn't.
all you need mathematically is the ability to iterate the argument,
which is why it works with any iterable.
and practically you'd like to have len() so you can avoid infloops.
I wonder if it does, in fact, use __len__ I haven't tested it, but it certainly does work with any iterable that isn't Sized.
The other thing you need mathematically to have a set is the 'in' operation. If mutable, you need an idempotent .add, and .remove.
no one is arguing that the ABC doesn't provide the minimum API for a mathematical set here.
Of course convenience counts. It's not obvious to me whether the convenience of having those methods outweighs the parsimony of only implementing the dunders.
I had to go look up "parsimony" to make sure -- and I still don't know what you're point is. Maybe that's not the word you meant? In fact, it's not obvious to me whether
there's *any* convenience to having those methods. Shouldn't we want to encourage the use of the more concise and less cluttered operators, which also have the advantage that either operand can provide the implementation?
Well: two points: 1) why does the built in set object have them? Maybe it shouldn't, but it does, so there is something to be said fro making other "Sets" in the standard library the same. 2) the advantage, maybe small, and made by the OP, is that the methods work on any iterable, rather than only on sets. Is that a big deal? not huge, but it is nice sometimes.
OK, sometimes that may not be an advantage. But even if you want to specify which operand will provide the implementation, you can use the explicit dunder.
no, you can't -- the dunder doesn't support arbitrary iterables: (`it` is an iterable that isn't much else) In [20]: s Out[20]: {1, 2} In [21]: s.union(it) Out[21]: {0, 1, 2, 3, 4} In [22]: s.__or__(it) Out[22]: NotImplemented In [23]: s.__or__(set(it)) Out[23]: {1, 2}
And while the proposed methods are not part of the Set ABC at this
point, they ARE part of the build in set object. And historically at least, people informally duck typed as often, or more often, than they subclassed from or registered with ABCs anyway.
If you want all of the methods of the built-in set, use it or derive from it, or construct one.
The OP didn't want to make their own, they wanted built in set like objects to behave more like sets (dict views, in particular). But anyway, if we're going to say "derive from it, or construct one." then why have ABCs at all ?!?
And even if they are not added to the ABC, they could still be added to the other set-like objects in the standard library -- are there any other than the dict views?
What's the point? You want to add "There should be two-- and preferably exactly two --obvious ways to do it" to the Zen?
tell that to the author of the built in set object -- that decision was made long ago. And if we're playing the zen game -- isn't "derive from it, or construct one." two ways? plus the ABC -- so that's three! Anyway, this is not a big deal to not add -- but it's not a big deal to add, either. -CHB -- Christopher Barker, PhD Python Language Consulting - Teaching - Scientific Software Development - Desktop GUI and Web Development - wxPython, numpy, scipy, Cython