Thu 21 Nov 2019 — Thu 21 Nov 2019

Metaclasses

This is a the class of a class. You might use it to generate classes.

Usually you should ignore metaclasses and use class decorators instead. They are for tricky metaprogramming for exceptional scenarios only.

type is dual-purpose:

  1. Tells you what type an object is.
  2. Generates new classes (it's the default metaclass).

str and int also act as metaclasses.

type("className", (parent_class_1, parent_class_2), {"class_attribute": 1})

To create your own metaclass, inherit from type:

class MyMetaClass(type):
    def __new__(cls, clsname, bases, dct, attr_prefix="prefix_goes_here_"):
	"""
	The `__new__` function is what actually creates the object
	that is passed to `__init__` as `self`.

	This metaclass prepends the value of `attr_prefix` to every
	attribute in the classes that use it.
	"""
	modified_attrs = {
	    f"{attr_prefix}{k}": v
	    for k, v in dct.items()
	}

	return super(MyMetaClass, cls).__new__(cls, clsname, bases, modified_attrs)

To use it:

class MyClass(object, metaclass=MyMetaClass, attr_prefix="hello_"):
    you = "x"

dir(MyClass())