如果第一个参数不是类,则 issubclass 引发异常

war*_*iuc 5 python

我正在开发一个 Python 应用程序,我需要多次检查对象是否是 DB 模型的子类。

我做了自己的功能来做到这一点:

def isModel(obj):
    return isinstance(obj, type) and issubclass(obj, Model)
Run Code Online (Sandbox Code Playgroud)

issubclass引发异常 obj is not a class,但我希望它只返回 False 如果obj不是一个类。

我认为最好制作另一个功能,而不是使用内置的issubclass

def _issubclass(obj, Klass):
    return isinstance(obj, type) and issubclass(obj, Klass)
Run Code Online (Sandbox Code Playgroud)

但是为什么内置issubclass不是这样制作的呢?什么原因?我错过了什么吗?


更新:

我有模型:

class BaseModel(object):
    id = Field(...)

class MyModel(BaseModel):
    deleted = Field(...)
Run Code Online (Sandbox Code Playgroud)

在一个函数中,我想检查一个参数是否是一个BaseModel

def update_model(model):
    assert isinstance(model, type) and issubclass(model, BaseModel), 'Must be a model'
Run Code Online (Sandbox Code Playgroud)

issubclass回答一个对象是否是给定类的子类的问题。如果对象是类实例,那么 IMO 的答案应该是“不,您的对象不是 BaseModel 子类,因为它根本不是类”。

在 Python 中是很正常的,而不是if something is not None or len(something) != 0使用if something而不是提高任何TypeError. 如果的第一个参数issubclass不是类,则引发 TypeError 有什么用处?

例如,有人问一只狗:“你是解决这个任务的合适人选吗?”,而不是回答“不”,狗说“我不是男人”。我问了某人一件事(是子类),他没有回答我的问题。

Len*_*bro 0

Isinstance 可能会做你想做的事。isinstance(obj, Klass)当 obj 是 Klass 子类的类的实例时,将返回 True。例子:

>>> class A(object):
...    pass
... 
>>> class B(A):
...    pass
... 
>>> obj = B()
>>> 
>>> isinstance(obj, A)
True
Run Code Online (Sandbox Code Playgroud)

“如果 issubclass 的第一个参数不是类,那么引发 TypeError 有什么用处?”

显式的比隐式的好。您将非类传递给 issubclass。这表明你做错了什么。因此你会得到一个错误。如果您确实想将实例传递给 issubclass,您可以捕获该错误:

try:
    isbasemodel = False
    if issubclass(x, BaseModel):
       isbasemodel = True
except TypeError:
    # Accept that we test non-classes:
    pass
Run Code Online (Sandbox Code Playgroud)

或者,当然,您可以做您所做的:额外检查。

但是,如果它没有引发错误,那么就不可能捕获传入实例的错误。

据我了解,您想要在 API 或类似中进行检查,确保传入的对象是 BaseModel 的子类,并且不应允许用户传入实例。IMO,正确的做法是如果他们传递了错误的东西,则引发 TypeError 。就像这样:

def update_model(model):
    if not issubclass(model, BaseModel):
        raise TypeError('Must be a model')
Run Code Online (Sandbox Code Playgroud)

在那里进行断言只是意味着您隐藏了这样一个事实:传入错误的内容是类型错误。