Issubclass throws an exception if the first argument is not a class

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

I made my own function for this:

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

issubclass throws an obj exception is not a class, but I would like it to simply return False if obj not a class.

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

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

But why the built-in issubclass not created like that? What reason? Did I miss something?


UPDATE:

I have models:

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

In the function, I want to check if the argument is BaseModel :

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

issubclass answers the question of whether the object is a subclass of this class. If the object is an instance of the class, so the IMO response should be "No, your object is not a subclass of BaseModel because it is not a class at all."

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

For example, someone asks a dog: β€œDo you solve this problem correctly?”, And instead of saying β€œNo”, the dog says: β€œI'm not a man.” I asked someone one (subclass), and he did not answer my question.

+4
source share
3 answers

Isinstance will probably do what you want. isinstance(obj, Klass) will return True if obj is an instance of a class that is a subclass of Klass. Example:

 >>> class A(object): ... pass ... >>> class B(A): ... pass ... >>> obj = B() >>> >>> isinstance(obj, A) True 

"What is the usefulness of raising a TypeError if the first argument of issubclass is not a class?"

Explicit is better than implicit. You passed a non-class to issubclass. This means that you are doing something wrong. Therefore, you receive an error message. If you seriously want to pass instances to issubclass, you can catch this error:

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

Or, of course, you can do what you do: an extra check.

However, if it did not cause an error, then it would be impossible to catch the transmission error in the instance.

From what I understand, you want to make a check in the API or similar that the object passed in is a subclass of BaseModel and the user is not allowed to pass in the instance. IMO, the right thing to do is raise a TypeError if they go wrong. For instance:

 def update_model(model): if not issubclass(model, BaseModel): raise TypeError('Must be a model') 

Making a statement there simply means that you are hiding the fact that it is a type error to convey the wrong thing.

0
source

Please read the docs for isinstance and issubclass . They explain everything.

You mean that "an object is a subclass of the database model", right? What will it be a class, not an instance of a class? Then isn't that what issubclass does? Why mess with a thing? - Chris Morgan just edited

+1
source

I found a more elegant way to use metaclasses (since 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 am using now.

+1
source

Source: https://habr.com/ru/post/1388786/


All Articles