Everything in Python is an object, including classes.
This means you can reference classes, passing them around like arguments, store them in attributes, (extra) names, lists, dictionaries, etc.
This is perfectly normal in Python:
class_map = {
'foo': A,
'bar': SomeOtherClass,
'baz': YetAnother,
}
instance = class_map[some_variable]()
Now it depends on some_variable
what class was picked to create an instance; the class_map
dictionary values are all classes.
Classes are themselves instances of their type; this is called their metaclass. You can produce a new class by calling type()
with a name, a sequence of base classes, and a mapping defining the attributes of the class:
type('DynamicClass', (), {'foo': 'bar'})
creates a new class object, with a foo
attribute set to bar
, for example. The class produced can itself then be used to create instances. So classes are produced by metaclasses, just as instances are produced by classes.
You can produce your own metaclasses by inheriting from type
, opening a weird and wonderful world of class behaviour.
Calling an unbound method by passing in a separate instance is not really a good example of using classes as an object. All you did was use the initial reference (the class name) to look up the method, then pass in an instance of the class as the first parameter to stand in for self
.