6

I've been hacking classes in Python like this:

def hack(f,aClass) :  class MyClass(aClass) :     def f(self) :       f()  return MyClassA = hack(afunc,A)

Which looks pretty clean to me. It takes a class, A, creates a new class derived from it that has an extra method, calling f, and then reassigns the new class to A.

How does this differ from metaclass hacking in Python? What are the advantages of using ametaclass over this?

1
  • What is the reason for doing this?CommentedMar 6, 2009 at 14:22

3 Answers3

5

The definition of a class in Python is an instance of type (or an instance of a subclass of type). In other words, the class definition itself is an object. With metaclasses, you have the ability to control the type instance that becomes the class definition.

When a metaclass is invoked, you have the ability to completely re-write the class definition. You have access to all the proposed attributes of the class, its ancestors, etc. More than just injecting a method or removing a method, you can radically alter the inheritance tree, the type, and pretty much any other aspect. You can also chain metaclasses together for a very dynamic and totally convoluted experience.

I suppose the real benefit, though is that the class's type remains the class's type. In your example, typing:

a_inst = A()type(a_inst)

will show that it is an instance ofMyClass. Yes,isinstance(a_inst, aClass) would returnTrue, but you've introduced a subclass, rather than a dynamically re-defined class. The distinction there is probably the key.

As rjh points out, the anonymous inner class also has performance and extensibility implications. A metaclass is processed only once, and the moment that the class is defined, and never again. Users of your API can also extend your metaclass because it is not enclosed within a function, so you gain a certain degree of extensibility.

This slightly old article actually has a good explanation that compares exactly the "function decoration" approach you used in the example with metaclasses, and shows the history of the Python metaclass evolution in that context:http://www.ibm.com/developerworks/linux/library/l-pymeta.html

Peter Mortensen's user avatar
Peter Mortensen
31.5k22 gold badges110 silver badges134 bronze badges
answeredMar 6, 2009 at 14:27
Jarret Hardie's user avatar
Sign up to request clarification or add additional context in comments.

Comments

1

You can use thetype callable as well.

def hack(f, aClass):    newfunc = lambda self: f()    return type('MyClass', (aClass,), {'f': newfunc})

I find usingtype the easiest way to get into the metaclass world.

Comments

1

A metaclass is the class of a class. IMO, the bloke here covered it quite serviceably, including some use-cases. See Stack Overflow question"MetaClass", "new", "cls" and "super" - what is the mechanism exactly?.

Comments

Your Answer

Sign up orlog in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

By clicking “Post Your Answer”, you agree to ourterms of service and acknowledge you have read ourprivacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.