Understanding Python Classes as Objects and Metaclasses
This article explains that in Python classes are objects, demonstrates how to assign, copy, and pass them, shows dynamic class creation with functions and the built‑in type, and introduces custom metaclasses for modifying class creation, concluding with practical ORM examples and advice on when to use metaclasses.
Before understanding metaclasses, you need to master Python classes. In Python, a class is an object created when the class statement is executed.
<code>class ObjectCreator(object):
pass
my_object = ObjectCreator()
print(my_object) # <__main__.ObjectCreator object at 0x...>
</code>Classes can be assigned to variables, copied, have attributes added, and passed as function arguments.
<code>print(ObjectCreator) # <class '__main__.ObjectCreator'>
def echo(o):
print(o)
echo(ObjectCreator)
print(hasattr(ObjectCreator, 'new_attribute'))
ObjectCreator.new_attribute = 'foo'
print(hasattr(ObjectCreator, 'new_attribute'))
print(ObjectCreator.new_attribute)
ObjectCreatorMirror = ObjectCreator
print(ObjectCreatorMirror())
</code>Because classes are objects, they can be created dynamically at runtime, for example inside a function.
<code>def choose_class(name):
if name == 'foo':
class Foo(object):
pass
return Foo
else:
class Bar(object):
pass
return Bar
MyClass = choose_class('foo')
print(MyClass) # <class '__main__.Foo'>
print(MyClass()) # <__main__.Foo object at 0x...>
</code>The built‑in type function can also create classes dynamically by receiving the class name, a tuple of base classes, and a dictionary of attributes.
<code>MyShinyClass = type('MyShinyClass', (), {})
print(MyShinyClass) # <class '__main__.MyShinyClass'>
print(MyShinyClass()) # <__main__.MyShinyClass object at 0x...>
</code>Using type with a dictionary is equivalent to defining the class with a class statement.
<code>Foo = type('Foo', (), {'bar': True})
</code>Metaclasses are the “class factories” that create class objects. The built‑in metaclass is type , but you can define custom metaclasses to intercept and modify class creation.
<code>class NothingMetaclass(type):
def __new__(mcs, name, bases, namespace):
# custom behavior here
return type.__new__(mcs, name, bases, namespace)
class Foo(object, metaclass=NothingMetaclass):
pass
</code>Demo 1 shows how __new__ and __init__ behave in a metaclass.
<code># MetaA example
class MetaA(type):
def __new__(cls, name, bases, dct):
print('MetaA.__new__')
return type.__new__(cls, name, bases, dct)
def __init__(cls, name, bases, dct):
print('MetaA.__init__')
class A(object, metaclass=MetaA):
pass
print(A())
</code>Demo 2 adds a method to a list class via a metaclass.
<code>class ListMetaclass(type):
def __new__(mcs, name, bases, namespace):
namespace['add'] = lambda self, value: self.append(value)
return type.__new__(mcs, name, bases, namespace)
class MyList(list, metaclass=ListMetaclass):
pass
l = MyList()
l.add(1)
print(l) # [1]
</code>Metaclasses are mainly used to build APIs such as Django’s ORM, where a simple class definition is transformed into a complex database mapping.
<code>class Person(models.Model):
name = models.CharField(max_length=30)
age = models.IntegerField()
</code>A minimal ORM demo illustrates how a custom metaclass can collect field definitions and generate SQL statements.
<code># Simplified ORM example (field, model, and save logic omitted for brevity)
</code>Conclusion: In Python everything is an object; classes are objects created by the metaclass type . While metaclasses are powerful, for most dynamic modifications simpler techniques like monkey‑patching or class decorators are preferable.
Python Programming Learning Circle
A global community of Chinese Python developers offering technical articles, columns, original video tutorials, and problem sets. Topics include web full‑stack development, web scraping, data analysis, natural language processing, image processing, machine learning, automated testing, DevOps automation, and big data.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.