darthbith
darthbith

Reputation: 19597

Why do Python metaclasses prohibit passing paramters to the __init__ method?

This question is related to this question about PyTables metaclasses. I was trying to subclass the IsDescription metaclass in PyTables, to define the shape of the Column by a variable:

import tables
class MyClass(tables.IsDescription):
    def __init__(self, param):
        var1 = tables.Float64Col(shape=(param))

MyClass1 = MyClass(12)

This throws the error: TypeError: object.__new__() takes no parameters. Using self.var1 = ... gives the same error.

In this SO question the same error is reported, and the reason is attributed to the fact that IsDescription is a metaclass.

My question (which is not answered at the linked question, and I haven't been able to find anything by Googling) is: why do metaclasses prohibit this functionality? Is it specific to this metaclass, or generic for all metaclasses?

Upvotes: 1

Views: 100

Answers (1)

Cyrille Pontvieux
Cyrille Pontvieux

Reputation: 2471

This is generic to all metaclasses. In fact a metaclass is instanciated when a class is being created and the parameters passed are always the same, and determine by python. Those are :

  • The name of the class to create
  • The list of inherited classes for this class. It's a tuple of class reference. By default, for new-style class it's object
  • The dictionary of all fields of the class to be created

You cannot pass you parameters here as this call is done automatically by the python interpreter. In python 2, a metaclass is defined as a __metaclass__ attribute in the class itself, whereas it's a argument in the definition in the class in Python 3.

The __new__ method of the metaclass is called just before the __init__ method of your class and so, takes the same arguments as your class. You can change the behavior of your class at initialization in the metaclass rather than in the constructor for instance.

If you want to define arguments to a metaclass, you can for example use some specific fields to be defined in the class to be defined. You can also write a function that will act like a metaclass to create a class for you, and you will be able to add parameters to that function. But I don't know PyTables and your exact requirements or possibilities.

Upvotes: 2

Related Questions