<div dir="ltr"><div class="gmail_default" style="color:#000000"><br></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, May 29, 2015 at 5:06 PM,  <span dir="ltr"><<a href="mailto:sohcahtoa82@gmail.com" target="_blank">sohcahtoa82@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class=""><br>
> For example, the new (in 3.4) Enum class uses a metaclass.<br>
><br>
>    class SomeEnum(Enum):<br>
>       first = 1<br>
>       second = 2<br>
>       third = 3<br>
><br>
> The metaclass changes normal class behavior to:<br>
><br>
>    - support iterating: list(SomeEnum) --> [SomeEnum.first, SomeEnum.second, SomeEnum.third]<br>
>    - support a length:  len(SomeEnum) --> 3<br>
>    - not allow new instances to be created:  --> SomeEnum(1) is SomeEnum(1)  # True<br>
><br>
> --<br>
> ~Ethan~<br>
<br>
</span>Regarding the first two, you can implement __iter__ and __len__ functions to create that functionality, though those functions would operate on an instance of the class, not the class itself.<br>
<br>
As for the third, can't you override the __new__ function to make attempts to create a new instance just return a previously created instance?<br></blockquote><div><br></div><div><div class="gmail_default" style="color:rgb(0,0,0);display:inline">​Of course, but with metaclasses you don't *have* to (in fact, that's the type of thing that the metaclass could do behind the scenes).</div></div><div><div class="gmail_default" style="color:rgb(0,0,0);display:inline"><br></div></div><div><div class="gmail_default" style="color:rgb(0,0,0)">​In this case, any Enum subclass should *always* behave as Ethan described -- without metaclasses that wouldn't necessarily be true (e.g., if the person creating an Enum subclass didn't bother to correctly implement __new__, __iter__, and __len__ for their subclass).</div><div class="gmail_default" style="color:rgb(0,0,0)"><br></div><div class="gmail_default" style="color:rgb(0,0,0)">By using metaclasses, you can declare an Enum subclass as simply as Ethan showed, since the metaclass does all of the dirty work implementing the desired behavior at the time the class object is constructed (subclasses inherit their parent class's metaclass).</div><div class="gmail_default" style="color:rgb(0,0,0)"><br></div><div class="gmail_default" style="color:rgb(0,0,0)">In this use-case, you can think of it as a kind of "implicit class factory".  Suppose you have a prescription for how you modify a class definition (i.e., by implementing certain behavior in __new__ or __init__) that you wrap up into some function "tweak_my_class".  The metaclass would allow the class definition to be the equivalent of something like:</div><div class="gmail_default" style="color:rgb(0,0,0)"><br></div><div class="gmail_default" style="color:rgb(0,0,0)">class MyClass(SubClass):</div><div class="gmail_default" style="color:rgb(0,0,0)">    # whatever</div><div class="gmail_default" style="color:rgb(0,0,0)"><br></div><div class="gmail_default" style="color:rgb(0,0,0)">MyClass = tweak_my_class(MyClass)</div><div class="gmail_default" style="color:rgb(0,0,0)"><br></div><div class="gmail_default" style="color:rgb(0,0,0)">Or as a class decorator</div><div class="gmail_default" style="color:rgb(0,0,0)"><br></div><div class="gmail_default" style="color:rgb(0,0,0)">@tweak_my_class</div><div class="gmail_default" style="color:rgb(0,0,0)">class MyClass(SubClass):</div><div class="gmail_default" style="color:rgb(0,0,0)">    # whatever</div><div class="gmail_default" style="color:rgb(0,0,0)"><br></div><div class="gmail_default" style="color:rgb(0,0,0)">(In fact, the `six` module allows you to implement metaclasses as decorators to work with both Python 2 and Python 3, but I think metaclasses are more powerful in Py3 than they are in Py2).​</div></div></div><div class="gmail_default" style="color:rgb(0,0,0)">​</div><div class="gmail_default" style="color:rgb(0,0,0)">They are cool ideas, and I've used them in my own code, but they do have a kind of magic-ness to them -- especially in codes that you didn't write but are working on.  As a result, I've recently started to prefer alternatives, but in some rare cases (like Enum, for example), they are just the best solution.</div><div class="gmail_default" style="color:rgb(0,0,0)"><br></div><div class="gmail_default" style="color:rgb(0,0,0)">All the best,</div><div class="gmail_default" style="color:rgb(0,0,0)">Jason</div>
</div></div>