40

This might be too much of an open ended question, but I'm just now learning about metaclasses in Python and I don't understand how a metaclass is any different than just having a child class inherit from the parent class, like

class child(parent):

Wouldn't this serve the same purpose of a metaclass? I guess maybe I don't understand the purpose of a metaclass.

user2897013
  • 441
  • 6
  • 12
  • How is this a duplicate? I'm not asking 'what is a metaclass', and I have read that thread a couple times. – user2897013 Oct 19 '13 at 07:41
  • I am specifically asking what is the difference between a metaclass and a child class inheriting from parent class, as stated in my question. – user2897013 Oct 19 '13 at 08:07
  • 2
    What you are asking is a subset of what is asked in that question, and if you read and understand the answer to that question, you'll understand the difference you're asking about. – BrenBarn Oct 19 '13 at 08:12

2 Answers2

12

The difference is that inheriting from a class does not affect how the class is created, it only affects how instances of the class are created. If you do:

class A(object):
    # stuff

class B(A):
    # stuff

then A does not have any opportunity to "hook in" when B is created. Methods of A may be called when an instance of B is created, but not when the class B itself is created.

Metaclasses allow you to define custom behavior for when a class is created. Refer to the question I marked as duplicate for examples of how metaclasses work, and convince yourself that there are effects in those examples that you can't achieve with normal inheritance.

BrenBarn
  • 242,874
  • 37
  • 412
  • 384
4
class AccessorType(type):
    def __init__(self, name, bases, d):
        type.__init__(self, name, bases, d)
        accessors = {}
        prefixs = ["get_", "set_", "del_"]

        for k in d.keys():
            v = getattr(self, k)
            for i in range(3):
                if k.startswith(prefixs[i]):
                    accessors.setdefault(k[4:], [None, None, None])[i] = v

        for name, (getter, setter, deler) in accessors.items():
            # create default behaviours for the property - if we leave
            # the getter as None we won't be able to getattr, etc..
            # [...] some code that implements the above comment
            setattr(self, name, property(getter, setter, deler, ""))
Sukrit Kalra
  • 33,167
  • 7
  • 69
  • 71
david
  • 6,303
  • 16
  • 54
  • 91