The type() function is commonly used with a single argument – the variable whose data type we want to check. It returns an existing type object – the type of the input variable. For instance, if passed an int like 123, it returns the int type.
However, there is another variant with three arguments:
type(name, bases, dict)
It creates a new type object. This can be used to create new classes dynamically.
Inputs
The three inputs are:
- name (str) = name of the new class (it becomes its
__name__attribute). - bases (tuple) = base classes of the new class (it becomes the
__bases__attribute); if empty the base class isobject. - dict (dict) = attribute and method definitions (the
__dict__attribute).
Example
For example, we can use type() to create a new class named Number, subclass of int:
Number = type(
'Number',
(int,),
{'is_even': lambda self: self % 2 == 0}
)
- The first argument is the name of the new class, which is
'Number'(the input is a string – with quotes). - The second argument is a tuple with a single item – the
intclass, which is the base class of the newNumberclass. The items are classes/types, not strings, so no quotes. - The third argument is a dict with a single item – the definition of a new method named
'is_even', which checks whether the number is even. Dict keys are attribute or method names as strings – with quotes.
Using the new class
Now we can create an instance of the new class Number and use its method is_even to check if a number is even:
>>> x = Number(6) >>> x.is_even() True >>> y = Number(7) >>> y.is_even() False
If we check the data type using type() function (with a single argument), we get the new Number type.
>>> type(y)
We can also use isinstance() to check that int is indeed a base class of Number.
>>> isinstance(y, int) True