<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Sun, Oct 5, 2014 at 7:36 PM, Steven D'Aprano <span dir="ltr"><<a href="mailto:steve@pearwood.info" target="_blank">steve@pearwood.info</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Sun, Oct 05, 2014 at 02:43:13PM -0700, Guido van Rossum wrote:<br>
<br>
> An alternative that wouldn't even require a metaclass would be to write a<br>
> helper function that looks the class object up by name after parsing<br>
> __qualname__. There are some limitations to this, e.g. classes defined<br>
> inside functions -- but that's already a suspect pattern anyway.<br>
<br>
I understand that "suspect pattern" doesn't mean "don't ever do this",<br>
but I wonder what aspect of defining classes inside a function is<br>
suspect. I think the suspect part is that each invocation of the<br>
function creates a new class which (at least in the naive case) has the<br>
same name, same functionality, and looks identical to the casual<br>
glance but actually isn't. So given:<br>
<br>
def maker():<br>
    class MyClass: pass<br>
    return MyClass<br>
<br>
x = maker()()<br>
y = maker()()<br>
<br>
assert isinstance(x, type(y))<br>
assert isinstance(y, type(x))<br>
<br>
<br>
both assertions will fail, which may confuse some people. There's<br>
probably also implications for pickling as well. Are these the only<br>
"suspect" parts of defining classes inside functions, or have I missed<br>
something else?<span class="HOEnZb"></span><br></blockquote></div><br></div><div class="gmail_extra">Those (and their variations, e.g. using these in except clauses) are the main concerns; it also generally bothers me when something "smallish" like a function contains something "larger" like a class, especially when the class is substantial. It's another case of "flat is better than nested".<br><br>The only non-evil use of this pattern that I can recall is in unit tests -- even when it is possible (as it usually is) to move the class definition to a spot outside the test method, that doesn't make the test code any clearer. Such classes are usually very small (e.g. overriding just one or two methods) and are only used within the unit test. (That latter property is really the saving grace.)<br clear="all"></div><div class="gmail_extra"><br>-- <br>--Guido van Rossum (<a href="http://python.org/~guido">python.org/~guido</a>)
</div></div>