issubclass that returns 在传递实例而不是 class 时为 False

issubclass that returns False when passing an instance instead of a class

我想让 issubclass 按如下方式工作:如果原始 issubclass 收到一个实例而不是 class,它只是 return False。我是否需要编写类似下面的函数,或者有更好的方法吗?

def my_issubclass(cls, parent):
    try:
        return issubclass(cls, parent)
    except: # issubclass() arg 1 must be a class
        return False

issubclass() 旨在在第一个参数不是 class 时引发异常,所以是的,如果您传入其他内容,它会引发 TypeError。这是因为在大多数情况下,混合 classes(类型)和实例会表明某处存在错误!

所以你的选择是捕获那个异常(只是那个异常,不要在这里玩口袋妖怪,你不想全部捕获):

def my_issubclass(obj, type_or_types):
    try:
        return issubclass(obj, type_or_types)
    except TypeError:  # issubclass() arg 1 must be a class
        return False

或者你可以先检查你是否真的有 class:

def my_issubclass(obj, type_or_types):
    return isinstance(obj, type) and issubclass(obj, type_or_types)

第一种形式被称为比许可或EAFP更容易请求宽恕,第二种是三思而后行[=32= 】,李白。您选择哪一个部分取决于风格偏好,部分取决于性能方面的考虑。如果您不经常将它与实例而不是 class 一起使用,则使用第一种形式,否则使用第二种形式。请参阅我在软件工程上对 Python Forgiveness vs. Permission and Duck Typing 的回答。

使用 boolint 的快速演示(是的,布尔类型是整数的子class):

>>> def my_issubclass_eafp(obj, type_or_types):
...     try:
...         return issubclass(obj, type_or_types)
...     except TypeError:  # issubclass() arg 1 must be a class
...         return False
...
>>> def my_issubclass_lbyl(obj, type_or_types):
...     return isinstance(obj, type) and issubclass(obj, type_or_types)
...
>>> my_issubclass_eafp(1, int)
False
>>> my_issubclass_eafp(bool, int)
True
>>> my_issubclass_lbyl(1, int)
False
>>> my_issubclass_lbyl(bool, int)
True