【问题标题】:issubclass that returns False when passing an instance instead of a classissubclass 在传递实例而不是类时返回 False
【发布时间】:2019-04-06 13:22:44
【问题描述】:

我想让issubclass 如下工作:如果原始issubclass 接收的是实例而不是类,它只会返回False。我是否需要编写类似下面的函数或者有更好的方法来做到这一点?

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

【问题讨论】:

  • 您可以预先检查 cls 是否实际上是一个类 (isinstance(cls, type)),但这是 EAFP vs LBYL 哲学的问题。不能做更多,我不知道你为什么要这样做?

标签: python class subclass


【解决方案1】:

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

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

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

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

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

第一种形式被称为比 Permission 或 EAFP 更容易请求宽恕,第二种形式是 Look Before You Leap,LBYL。您选择哪一个部分基于样式偏好,部分基于性能考虑。如果您不经常将它与实例而不是类一起使用,则使用第一种形式,否则使用第二种形式。请参阅我在软件工程上对Python Forgiveness vs. Permission and Duck Typing 的回答。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-28
    • 1970-01-01
    • 2021-06-04
    • 2023-03-20
    • 2015-05-11
    • 2012-08-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多