views:

318

answers:

4

1. Passing configuration to the __init__ method which calls register implicitely:

class Base:

    def __init__(self, *verbs):
        if not verbs:
          verbs = "get", "post"
        self._register(verbs)

    def _register(self, *verbs):
        pass


class Sub(Base):

    def __init__(self):
        super().__init__("get", "post", "put")

2. Calling register explicitely in the subclass' __init__ method:

class Base:

    def __init__(self):
        self._register("get", "post")

    def _register(self, *verbs):
        pass


class Sub(Base):

    def __init__(self):
        self._register("get", "post", "put")

I use Python 3.

What is better or more pythonic? Or is it only a matter of taste?

A: 

If everything extending the base class will behave like this, I would personally call from the base class's constructor. If not, and the behaviour varies, I would call from the sub class...

As for what is more Pythonic - don't subscribe to a cult - write code that works...

Martin

Martin Milan
`write what works` -- the most often-heard excuse for utterly unmaintainable code. arguments in favor of convention are myriad and convincing. http://en.wikipedia.org/wiki/Coding_conventions
Igor
As I was describing Python to a colleague yesterday it became blindingly obvious why the conventions prescribed in various PEPs and other docs are a core value of the practice of Python: intention is hard to formalize, when the language provides a way to codify intention, use it.
msw
What do you mean with "everything extending the base class will behave like this"? In most cases the default value will be fine, but my question is about what to do if the value has to be set.
deamon
What I meant by "write code that works", qualified as it was by "don't subscribe to a cult", was don't get bogged down in all the Monty laiden tutorials on the web, or focus too much on Python itself. Get a good grounding in OOP first, because that is where the answer to this question lies - not in a language specific manual.
Martin Milan
deamon - What I meant by "If everything extending the base class will behave like this" is will every class that you derive from the base also call the _register method, and with the same arguments. If not, then the call doesn't belong in the base clas - but rather in the subclasses. Also consider that it *may* be a good idea to insert something between the Base class and what you currently intend as it's subclasses in the type heirarchy. It's always worth spending a few moments rechecking your class design - even if you come back to the same answer...
Martin Milan
Oh - and Igor, I agree with the importance of coding conventions - but I'm not sure if that is really what we're talking about here - I think we're more looking at class hierarchy design.
Martin Milan
A: 

IMHO, the second way is better. The 'more pythonic' way is to make things as explicit as practical. You won't have to go track down the parent class constructor to see what it's doing with those arguments...

Igor
-1 (by accident, sorry I had +1, then reconsidered, hit -1 -1 inadvertently and it has locked my error). The reason I meant +0 is that in example 2, you still need to back-reference to Base._register to know what is happening so it isn't clear which is more explicit.
msw
@msw: presumably, the function won't be called `register` -- it'll be called `registerValidVerbs` or something; also, the names of the class itself and the various variables will give you at least some context about what's going on. in example 1, all you know is that some stuff is getting passed to the parent constructor. you have no idea what the parent constructor is going to do with that stuff.
Igor
+1  A: 

I think none of these options is good. The closest solution would probably be:

class Base(object):

    def __init__(self):
        self._register("get", "post")


class Sub(Base):

    def __init__(self):
        super(Sub, self).__init__()
        self._register("put")

I'm also wondering if it wouldn't be better to register the verbs at the class level. They are probably identical for all instances, so why are they registered for each instance individually?

nikow
Class level or instance level doesn't really matter, because I use singletons.
deamon
A: 

I would definitely use the first form. The question I would ask myself is: "What if the initialization for the base class is modified, one day? do I want subclasses to benefit from the update or not?". In almost all of my code, the answer is a resounding yes… :)

EOL