20

In Python you have the None singleton, which acts pretty oddly in certain circumstances:

>>> a = None
>>> type(a)
<type 'NoneType'>
>>> isinstance(a,None)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: isinstance() arg 2 must be a class, type, or tuple of classes and types

So first off, <type 'NoneType'> displays that None is not a type, but that NoneType is. Yet when you run isinstance(a,NoneType), it responds with an error: NameError: name 'NoneType' is not defined

Now, given this, if you have a function with an input default set to None, and need to check, you would do the following:

if variable is None:
    #do something
else:
    #do something

what is the reason that I cannot do the following instead:

if isinstance(variable,None): #or NoneType
    #do something
else:
    #do something

I am just looking for a detailed explanation so I can better understand this

Edit: good application

Lets say I wanted to use isinstance so that I can do something if variable is a variety of types, including None:

if isinstance(variable,(None,str,float)):
    #do something
1
  • 2
    if variable == None is anti-idiomatic Python. The standard way to do this test is by making use of the fact that None is a singleton: use if variable is None instead. Commented Jun 19, 2013 at 18:21

4 Answers 4

32

You can try:

>>> variable = None
>>> isinstance(variable,type(None))
True
>>> variable = True
>>> isinstance(variable,type(None))
False

isinstance takes 2 arguments isinstance(object, classinfo) Here, by passing None you are setting classinfo to None, hence the error. You need pass in the type.

Sign up to request clarification or add additional context in comments.

Comments

24

None is not a type, it is the singleton instance itself - and the second argument of isinstance must be a type, class or tuple of them. Hence, you need to use NoneType from types.

from types import NoneType
print isinstance(None, NoneType)
print isinstance(None, (NoneType, str, float))
True
True

Although, I would often be inclined to replace isinstance(x, (NoneType, str, float)) with x is None or isinstance(x, (str, float)).

4 Comments

Good answer and explanation, but I accepted karthikr because it did not require an import
@RyanSaxe It's alright, I forgive you. But if you plan on using NoneType a lot I would just import it from types. It seems unnecessary to call type(None) when you can easily access that value.
There is no longer a NoneType reference in types. You may use NoneType = type(None)
I like this answer because it normalizes my code, rather than handle the case of None differently
4

None is the just a value of types.NoneType, it's not a type.

And the error is clear enough:

TypeError: isinstance() arg 2 must be a class, type, or tuple of classes and types

From the docs:

None is the sole value of types.NoneType. None is frequently used to represent the absence of a value, as when default arguments are not passed to a function.

You can use types.NoneType

>>> from types import NoneType
>>> isinstance(None, NoneType)
True

is operator also works fine:

>>> a = None
>>> a is None
True

Comments

3

None is a value(instance) and not a type. As the error message shows, isinstance expects the second argument to be a type.

The type of None is type(None), or Nonetype if you import it (from types import NoneType)

Note: the idiomatic way to do the test is variable is None. Short and descriptive.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.