Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is subclassing from object the same as defining type as metaclass?

This is an old-style class:

class OldStyle:
    pass

This is a new-style class:

class NewStyle(object):
    pass

This is also a new-style class:

class NewStyle2:
    __metaclass__ = type

Is there any difference whatsoever between NewStyle and NewStyle2?

I have the impression that the only effect of inheriting from object is actually to define the type metaclass, but I cannot find any confirmation of that, other than that I do not see any difference.

like image 477
zvone Avatar asked Sep 15 '16 01:09

zvone


People also ask

What is __ metaclass __ in Python?

A metaclass in Python is a class of a class that defines how a class behaves. A class is itself an instance of a metaclass. A class in Python defines how the instance of the class will behave. In order to understand metaclasses well, one needs to have prior experience working with Python classes.

How do you set the metaclass of class A to B?

In order to set metaclass of a class, we use the __metaclass__ attribute. Metaclasses are used at the time the class is defined, so setting it explicitly after the class definition has no effect.

Are Metaclasses inherited?

Defining Metaclasses Principially, metaclasses are defined like any other Python class, but they are classes that inherit from "type". Another difference is, that a metaclass is called automatically, when the class statement using a metaclass ends.

Why do we need Metaclasses?

A rule of thumb is this: it makes sense to use metaclasses if you have a scenario in which you need to change how a class is instantiated. Decorators don't quite give you just that because the class actually is instantiated before you do anything with a decorator.


1 Answers

Pretty much yes, there's no difference between NewStyle and NewStyle2. Both are of type type while OldStyle of type classobj.

If you subclass from object, the __class__ of object (meaning type) is going to be used; if you supply a __metaclass__ that is going to get picked up.

If nothing is supplied as __metaclass__ and you don't inherit from object, Py_ClassType is assigned as the metaclass for you.

In all cases, metaclass.__new__ is going to get called. For Py_ClassType.__new__ it follows the semantics defined (I've never examined them, really) and for type.__new__ it makes sure to pack object in the bases of your class.

Of course, a similar effect is achieved by:

cls = type("NewStyle3", (), {})

where a call is immediately made to type; it's just a bigger hassle :-)

like image 106
Dimitris Fasarakis Hilliard Avatar answered Oct 14 '22 14:10

Dimitris Fasarakis Hilliard