In Python, the comparison operators -- <
, <=
, ==
, !=
, >
, >=
-- can be implemented to mean whatever is relevant to the implementing class. In Python 2 that was done by overriding __cmp__
, and in Python 3 by overriding __lt__
and friends. What is the advantage of having an issubclass()
built-in method instead of allowing for expressions such as bool < int
(true), int < object
(true), int <= int
, or int < float
(false). In particular, I'll note that classes ordered by issubclass()
constitutes a partially ordered set in the mathematical sense.
The Python 3 equivalent of what I'm thinking would look like what's below. This code doesn't replace issubclass()
(though looping over the MRO would accomplish that, right?). However, wouldn't this be more intuitive?
@functools.total_ordering
class Type(type):
"Metaclass whose instances (which are classes) can use <= instead issubclass()"
def __lt__(self, other):
try:
return issubclass(self, other) and self != other
except TypeError: # other isn't a type or tuple of types
return NotImplemented
def __eq__(self, other):
if isinstance(other, tuple): # For compatibility with __lt__
for other_type in other:
if type(self) is type(other_type):
return False
return True
else:
return type(self) is type(other)
Actual Question: What is the advantage of having an issubclass() built-in method instead of allowing for expressions such as bool < int (true), int < object (true), int <= int, or int < float (false).
Because it would be against the Zen of Python: http://www.python.org/dev/peps/pep-0020/
Explicit is better than implicit.
If you look at the following line of code in isolation:
issubclass(a, b)
It's perfectly obvious that a
and b
are variables containing classes and we are checking if a
is a subclass of b
. And if they happen to not contain classes, you'll know.
But looking at this
a < b
Would not tell you anything. You need to examine the surrounding code to determine they contain classes before you know that we are checking if the class in a
is a subclass of b
. And if say a=5 and b=6 it will still run "fine".
But Python is flexible, so if you really want this, you can implement a base type with such behaviour as you've shown.
Actually - as an aside - the prevalence of overloading operators in C++ for example is a significant drawback of the language (at least in my eyes) because when you see a + b
it might as well launch a nuclear missile for all you know.... until you check types of a/b, look up the class implementation and +
operator overload implementation (if any... and if not see if the parent class has any.... and if not see if the parent parent...)