Python历史和设计:为什么使用issubclass()而不是丰富的比较?

时间:2012-04-10 20:03:22

标签: python computer-science language-design language-history

在Python中,比较运算符 - <<===!=>>= - 可以是实现意味着与实现类相关的任何内容。在Python 2中,通过覆盖__cmp__来完成,在Python 3中通过覆盖__lt__和朋友来完成。使用issubclass()内置方法而不是允许bool < int(true),int < object(true),int <= int或{{等int < float等表达式的优点是什么? 1}}(假)。特别是,我会注意到issubclass()排序的类在数学意义上构成partially ordered set

Python 3等同于我的想法,看起来就像下面的内容。此代码不会替换issubclass()(尽管在MRO上循环可以实现这一点,对吧?)。但是,这不是更直观吗?

@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)

实际问题:使用issubclass()内置方法而不是允许表达式如bool&lt; int(true),int&lt; object(true),int&lt; = int或int&lt;浮动(假)。

3 个答案:

答案 0 :(得分:2)

粗体的一个优点:

  

issubclass(class, classinfo)

     

如果class是classinfo的子类(直接,间接或虚拟),则返回true。类被认为是其自身的子类。 classinfo可能是类对象的元组,在这种情况下,将检查classinfo中的每个条目。在任何其他情况下,都会引发TypeError异常。

另一个是它的描述性;并非所有使用Python的人都是数学家。

答案 1 :(得分:2)

因为它会违反Python的禅宗:http://www.python.org/dev/peps/pep-0020/

Explicit is better than implicit.

如果您单独查看以下代码行:

issubclass(a, b)

很明显,ab是包含类的变量,我们正在检查a是否是b的子类。如果他们碰巧不包含课程,你就会知道。

但是看着这个

a < b

不会告诉你任何事情。在知道我们正在检查a中的类是否为b的子类之前,您需要检查周围的代码以确定它们是否包含类。如果说a = 5且b = 6,它仍将“正常”运行。

但是Python很灵活,所以如果真的想要这个,你可以用你所展示的行为来实现一个基类型。

实际上 - 作为一个例外 - 例如C ++中重载运算符的普遍存在是该语言的一个重大缺点(至少在我看来),因为当你看到a + b时它也可能发射核导弹所有你知道....直到你检查a / b的类型,查找类实现和+运算符重载实现(如果有的话...如果没有看到父类有任何....如果没有看到父母......)

答案 2 :(得分:0)

我会说优势是无效的。唯一的技术差异是<是中缀。

但这个问题与技术问题无关。它似乎与语义和易读性有关。

使用<表示订单。虽然类层次结构可以解释为“可订购”,但它总是一个近似值。对许多人来说,这是一个非显而易见的问题。

使用issubclass更加清晰,仍然很简单,并且除了它实际上的做法之外不会有任何其他解释:检查object / classinfo是否是{的子类{1}}。

简单,简单,明确,有效。这些都是优点。也许你没有/不能利用它们。但这已经是个人品味了。