Python in Detail: Even Classes Are Objects
Welcome to the Even Classes Are Objects lesson!
This lesson is shown as static text below. However, it's designed to be used interactively. Click the button below to start!
In an earlier lesson, we saw that every Python value has attributes. In this lesson, we'll see that every value in Python is an instance of some class.
We've already used the
type(...)function to get a value's class.>
type(5).__name__Result:
When we call
type(x), it returnsx.__class__. We can also access that attribute directly.>
(5).__class__.__name__Result:
>
("Amir").__class__.__name__Result:
'str'
Our functions are instances of the
functionclass.>
def double(x):return x * 2double.__class__.__name__Result:
'function'
In Python, classes themselves are also values: we can put them in variables, pass them as functions, etc.
>
class Cat:def __init__(self, name):self.name = namesome_class = Catcat = some_class("Keanu")cat.nameResult:
'Keanu'
If classes are values, and all values are instances of a class, then what's the class of a class?
>
class Cat:passCat.__class__.__name__Result:
This may seem strange, but it's also consistent! In Python, "type" is sometimes used as a synonym for "class". A class like
Catis an instance oftype.In that example, we accessed
type's.__name__attribute.typeitself is a class, which must be a value, so it must be an object. What's the class oftype?>
type.__class__.__name__Result:
Classes are instances of the
typeclass. Buttypeitself is also a class, sotypeis an instance of itself.If
typeis a class, then we can instantiate it like any other class. Instantiatingtypeis a way to build a new type (a new class). The next example defines aPointclass. But instead of using the regular class syntax, we build the class up piece by piece, starting with a call totype(...).>
# This function will become our Point class's constructor.def __init__(self, x, y):self.x = xself.y = y# We build the `Point` class by instantiating the `type` class. It takes a# name for the new class, a tuple of base classes, and a dictionary of# attributes for the class.Point = type("Point",(object, ),{"__init__": __init__,})# Now we have our `Point` class, which works like any other class!p = Point(2, 3)(p.x, p.y)Result:
(2, 3)
This isn't a good way to define a new class in practice. But it shows us how far Python goes in exposing its internals, and in treating everything as an object. Even the
classsyntax is just a more convenient way to instantiate thetypeclass.You've reached the end of this course! We thought that this was a good place to end, since it highlights how dynamic Python is. We hope that you enjoyed it!