[Python-ideas] Classes inside functions [was Re: Add __parent__ to all classes, functions, and modules]

Guido van Rossum guido at python.org
Mon Oct 6 19:23:42 CEST 2014


On Mon, Oct 6, 2014 at 8:07 AM, Andrew Barnert <
abarnert at yahoo.com.dmarc.invalid> wrote:

> On Oct 5, 2014, at 20:04, Guido van Rossum <guido at python.org> wrote:
>
> On Sun, Oct 5, 2014 at 7:36 PM, Steven D'Aprano <steve at pearwood.info>
> wrote:
>
>> On Sun, Oct 05, 2014 at 02:43:13PM -0700, Guido van Rossum wrote:
>>
>> > An alternative that wouldn't even require a metaclass would be to write
>> a
>> > helper function that looks the class object up by name after parsing
>> > __qualname__. There are some limitations to this, e.g. classes defined
>> > inside functions -- but that's already a suspect pattern anyway.
>>
>> I understand that "suspect pattern" doesn't mean "don't ever do this",
>> but I wonder what aspect of defining classes inside a function is
>> suspect. I think the suspect part is that each invocation of the
>> function creates a new class which (at least in the naive case) has the
>> same name, same functionality, and looks identical to the casual
>> glance but actually isn't.
>
>>
> There's
>> probably also implications for pickling as well. Are these the only
>> "suspect" parts of defining classes inside functions, or have I missed
>> something else?
>>
>
> 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".
>
> The only non-evil use of this pattern that I can recall is in unit tests
>
>
> I agree that returning a class from a function is an uncommon special
> case, and any code that does so ought to have a good and obvious reason.
> But to say that such functions are evil doesn't seem right.
>

I didn't say *all* uses (or all uses outside unit tests) are evil. I still
maintain that most non-test code doing this has a bad smell and is
difficult to maintain.

>
> What about the functional constructors for namedtuple, or the two kinds of
> enums? Or a custom kind of enum (strings, bitsets, ...), which the PEP
> specifically suggests building on top of the stdlib support? Or something
> more inherently dynamic like a bridge library? Even in cases like
> generating an ORM from a SQL dump or a client from an RPC discovery
> call, which could be moved to a separate "pre-compilation" phase of
> building your application, is a function that generates source code for a
> class less suspect than one that just generates a class?
>

How namedtuple is implemented should be nobody's business, except
Raymond's, and it certainly isn't a pattern to be recommended. That's why
it's in the stdlib -- so you don't have to write such code yourself. Same
for enums. Yes, it *can* be done. But it takes superhuman skills to get it
right and it still won't be maintainable (TBH, every time I see the
namedtuple implementation I have to resist the urge to rewrite it. :-)

-- 
--Guido van Rossum (python.org/~guido)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20141006/452ceba1/attachment-0001.html>


More information about the Python-ideas mailing list