Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>OK, you've thrown quite a few concepts into the mix here! I'm going to pull out a few of the specific questions you have.</p> <p>In general, understanding super, the MRO and metclasses is made much more complicated because there have been lots of changes in this tricky area over the last few versions of Python.</p> <p><a href="http://docs.python.org/reference/datamodel.html" rel="nofollow noreferrer">Python's own documentation</a> is a very good reference, and completely up to date. There is an <a href="http://www.ibm.com/developerworks/linux/library/l-pymeta.html" rel="nofollow noreferrer">IBM developerWorks article</a> which is fine as an introduction and takes a more tutorial-based approach, but note that it's five years old, and spends a lot of time talking about the older-style approaches to meta-classes.</p> <p><strong><code>super</code></strong> is how you access an object's super-classes. It's more complex than (for example) Java's <code>super</code> keyword, mainly because of multiple inheritance in Python. As <a href="http://fuhm.net/super-harmful/" rel="nofollow noreferrer">Super Considered Harmful</a> explains, using <code>super()</code> can result in you implicitly using a chain of super-classes, the order of which is defined by the <a href="http://www.python.org/download/releases/2.3/mro/" rel="nofollow noreferrer">Method Resolution Order</a> (MRO).</p> <p>You can see the MRO for a class easily by invoking <code>mro()</code> on the class (not on an instance). Note that meta-classes are not in an object's super-class hierarchy.</p> <p><a href="https://stackoverflow.com/users/17624/thomas-wouters">Thomas</a>' description of meta-classes <a href="https://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python">here</a> is excellent:</p> <blockquote> <p>A metaclass is the class of a class. Like a class defines how an instance of the class behaves, a metaclass defines how a class behaves. A class is an instance of a metaclass.</p> </blockquote> <p>In the examples you give, here's what's going on:</p> <ol> <li><p>The call to <code>__new__</code> is being bubbled up to the next thing in the MRO. In this case, <code>super(MyType, cls)</code> would resolve to <code>type</code>; calling <code>type.__new__</code> lets Python complete it's normal instance creation steps.</p></li> <li><p>This example is using meta-classes to enforce a singleton. He's overriding <code>__call__</code> in the metaclass so that whenever a class instance is created, he intercepts that, and can bypass instance creation if there already is one (stored in <code>cls.instance</code>). Note that overriding <code>__new__</code> in the metaclass won't be good enough, because that's only called when creating the <em>class</em>. Overriding <code>__new__</code> on the class would work, however.</p></li> <li><p>This shows a way to dynamically create a class. Here's he's appending the supplied class's name to the created class name, and adding it to the class hierarchy too.</p></li> </ol> <p>I'm not exactly sure what sort of code example you're looking for, but here's a brief one showing meta-classes, inheritance and method resolution:</p> <pre><code>class MyMeta(type): def __new__(cls, name, bases, dct): print "meta: creating %s %s" % (name, bases) return type.__new__(cls, name, bases, dct) def meta_meth(cls): print "MyMeta.meta_meth" __repr__ = lambda c: c.__name__ class A(object): __metaclass__ = MyMeta def __init__(self): super(A, self).__init__() print "A init" def meth(self): print "A.meth" class B(object): __metaclass__ = MyMeta def __init__(self): super(B, self).__init__() print "B init" def meth(self): print "B.meth" class C(A, B): __metaclass__ = MyMeta def __init__(self): super(C, self).__init__() print "C init" &gt;&gt;&gt; c_obj = C() meta: creating A (&lt;type 'object'&gt;,) meta: creating B (&lt;type 'object'&gt;,) meta: creating C (A, B) B init A init C init &gt;&gt;&gt; c_obj.meth() A.meth &gt;&gt;&gt; C.meta_meth() MyMeta.meta_meth &gt;&gt;&gt; c_obj.meta_meth() Traceback (most recent call last): File "mro.py", line 38, in &lt;module&gt; c_obj.meta_meth() AttributeError: 'C' object has no attribute 'meta_meth' </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload