Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

issubclass raises exception if first argument is not a class

Tags:

python

I am developing a Python application where i need many times to check if an object is a subclass of a DB model.

I did my own function to do that:

def isModel(obj):
    return isinstance(obj, type) and issubclass(obj, Model)

issubclass raises exception of obj is not a class, but i would like it just return False if obj is not a class.

I thought better to make another function, to use instead of the built-in issubclass:

def _issubclass(obj, Klass):
    return isinstance(obj, type) and issubclass(obj, Klass)

But why the built-in issubclass was not made like that? What's the reason? Am i missing something?


UPDATE:

I have models:

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

class MyModel(BaseModel):
    deleted = Field(...)

In a function i want check if an argument is a BaseModel:

def update_model(model):
    assert isinstance(model, type) and issubclass(model, BaseModel), 'Must be a model'

issubclass answers the question if an object is a sub-class of the given class. If the object is a class instance, so the answer, IMO, should be 'No, your object is not a BaseModel subclass, because it's not a class at all'.

In Python is quite normal instead of if something is not None or len(something) != 0 to use if something and not raising any TypeError. What's the usefulness of raising TypeError if the first argument of issubclass is not a class?

For example someone asks a dog: 'Are you the right man to solve this task?', and instead of answering 'No', the dog says 'I am not a man'. I asked someone one thing (is sub class) and he didn't answer my question.

like image 256
warvariuc Avatar asked Nov 14 '22 12:11

warvariuc


1 Answers

I found a more elegant way using metaclasses (as my models use them anyway):

Python 2.7.2+ (default, Oct  4 2011, 20:06:09) 
[GCC 4.6.1] on linux2

>>> class ModelMeta(type):
...     "Metaclass for models"
... 
>>> class Model(object):
...     "DB model"
...     __metaclass__ = ModelMeta
... 
>>> class MyModel(Model):
...     "A real model"
... 
>>> isinstance(MyModel, type) and issubclass(MyModel, Model)
True
>>> myModelInstance = Model()
>>> issubclass(MyModel, Model)
True
>>> issubclass(myModelInstance, Model)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: issubclass() arg 1 must be a class
>>> isinstance(MyModel, type) and issubclass(MyModel, Model)
True
>>> isinstance(myModelInstance, type) and issubclass(myModelInstance, Model)
False
>>> isinstance(MyModel, ModelMeta)
True
>>> isinstance(myModelInstance, ModelMeta)
False
>>> 

So, isinstance(MyModel, ModelMeta) is what i use now.

like image 185
warvariuc Avatar answered Jan 08 '23 02:01

warvariuc