constructor classmethods

Chris Angelico rosuav at gmail.com
Wed Nov 2 10:03:35 EDT 2016


On Thu, Nov 3, 2016 at 12:46 AM,  <stestagg at gmail.com> wrote:
> We've got a colleague who is very keen that __init__ methods don't contain any logic/implementation at all, and if there is any, then it should be moved to a create() classmethod.
>
> I get the underlying principal, and it's one that a strict OOp approach would suggest, but my gut feeling is that this is not a pythonic approach at all.
>
> What do people feel about this?

Will you ever call the normal constructor? If the class depends on a
queue, as in your example, what happens if you call it with the same
queue as another instance is using, or something other than a queue,
etc, etc, etc? What this model does is introduce a whole lot of new
bug possibilities, for no particular reason.

I'll split your rationale into two:

> The rationale is that it decouples the class from the queue implementation (no evidence or suggestion that we would actually ever want to change impl in this case),
>

Then don't bother. YAGNI. No benefit unless you actually know you want this.

> and makes testing easier.
>

This is an important consideration, but shouldn't infect the primary
API. Design __init__ for normal usage, and if you need a mock queue
for testing, design an alternative way to construct one with a mock
queue. One way is to subclass your class to make a "mocked_class",
which then uses a mocked queue and whatever else it needs; another way
would be a static "_create_for_testing" function. Or you could just
create one as normal, then reach inside and replace its queue, but
that seems a tad risky (at very least, I'd make a method
"_replace_queue_for_testing" in the main class, so you have a chance
of noticing the problem as you're editing).

Ideally, testing should be done on the exact same code that you're
running, because otherwise you risk proving nothing. Minimize the code
used specifically for testing, and try to isolate it where possible.
And only warp the code when you *know* you need to - don't craft your
class's API around "well, we *might* need this for testing".

ChrisA



More information about the Python-list mailing list