FAQ
I was wondering, why you always have to remember to call bases'
constructors explicitly from the derived class constructor? Why hasn't
this been enforced by the language?

Search Discussions

  • Rene Pijlman at Apr 25, 2006 at 10:41 am
    cctv.star at gmail.com:
    I was wondering, why you always have to remember to call bases'
    constructors explicitly from the derived class constructor? Why hasn't
    this been enforced by the language?
    Probably because the language doesn't know whether the subclass wants to
    override its base class's constructor, or enhance it.

    --
    Ren? Pijlman
  • Diez B. Roggisch at Apr 25, 2006 at 10:45 am

    cctv.star at gmail.com wrote:

    I was wondering, why you always have to remember to call bases'
    constructors explicitly from the derived class constructor? Why hasn't
    this been enforced by the language?
    I have another question for you: why does JAVA enforce that a constructor of
    a base-class must be called prior to everything else in the derived class's
    constructor? No way to do some computing for parameters that I want to pass
    to the parent constructor...


    Besides, this automatically base-constructor-calling only happens for the
    most trivial of cases - the no-argument-constructors.

    Regards,

    Diez
  • Cctv Star at Apr 25, 2006 at 11:05 am

    Diez B. Roggisch wrote:
    I have another question for you: why does JAVA enforce that a constructor of
    a base-class must be called prior to everything else in the derived class's
    constructor?
    Well, I can imagine it's done to make sure that the base(s) are
    properly constructed. Sound s sensible to me.
    No way to do some computing for parameters that I want to pass
    to the parent constructor...
    Try this:

    Derived::Dreived() : Base(calcParam1(), calcParam2())
    ...
    Besides, this automatically base-constructor-calling only happens for the
    most trivial of cases - the no-argument-constructors.
    Well, the language can at least ensure that theconstructor is called -
    i.e. either call it automatically if it can be called without
    parameters, or fail with error.
  • Diez B. Roggisch at Apr 25, 2006 at 11:19 am

    Well, I can imagine it's done to make sure that the base(s) are
    properly constructed. Sound s sensible to me.
    It often is - there are popular examples in python where missing a
    constructor will cause a program to fail spectacular. But is it _always_ a
    sensible thing to do? No. If you only want some code inherited, but set up
    the required constraints to do so yourself. Such things can't be expressed
    in C++/JAVA, but that doesn't mean they aren't the sensible solution in
    some cases.
    No way to do some computing for parameters that I want to pass
    to the parent constructor...
    Try this:

    Derived::Dreived() : Base(calcParam1(), calcParam2())
    ...
    Oh, I know about that. however, there are limits to this. For example, you
    can't do anything that depends on constructors called before in case of
    multiple inheritance. And you are forced to create a static method to do
    so, which can be viewed as ugly as well.
    Well, the language can at least ensure that theconstructor is called -
    i.e. either call it automatically if it can be called without
    parameters, or fail with error.
    Yes, it can do that because of static typing - in fact it will fail on a lot
    more of occasions with a compilation error.

    The question here is if you are willing to trade freedom of expressiveness
    against the proposed security of static typing. I found that I favor the
    former and can live without the latter.

    Diez
  • Heiko Wundram at Apr 25, 2006 at 10:48 am

    Am Dienstag 25 April 2006 12:34 schrieb cctv.star at gmail.com:
    I was wondering, why you always have to remember to call bases'
    constructors explicitly from the derived class constructor? Why hasn't
    this been enforced by the language?
    Because sometimes you don't want to call the base classes constructors? The
    Python zen says: "Better explicit than implicit," and in this case it hits
    the nail on the head. Better to see right away what your code does (the
    explicit call to the base class), than to have to work around calling a bases
    constructor if you don't want to call it.

    --- Heiko.
  • Cctv Star at Apr 25, 2006 at 11:08 am

    Heiko Wundram wrote:
    Because sometimes you don't want to call the base classes constructors?
    Sounds strange to me at the moment, but I'll try to adjust to this
    thought.
    Python zen says: "Better explicit than implicit," and in this case it hits
    the nail on the head. Better to see right away what your code does (the
    explicit call to the base class), than to have to work around calling a bases
    constructor if you don't want to call it.
    Thanks, that explains it somehow - at least, it's consistent with
    explicit "self".
    I think I'll need some shift in thinking after C++.
  • Rene Pijlman at Apr 25, 2006 at 11:15 am
    cctv.star at gmail.com:
    I think I'll need some shift in thinking after C++.
    +1 qotw

    --
    Ren? Pijlman
  • Duncan Booth at Apr 25, 2006 at 11:29 am

    cctv.star at gmail.com wrote:

    Heiko Wundram wrote:
    Because sometimes you don't want to call the base classes constructors?
    Sounds strange to me at the moment, but I'll try to adjust to this
    thought.
    It makes sense in more static languages such as C++. The base class is
    initialised by the constructor, so you have to do everything possible to
    ensure that initialisation is done before you actually try to use any part
    of the base class. Weird things can still happen in C++ if you start
    calling methods too soon (e.g. to calculate some of the base constructor's
    parameters): you can find uninitialised member variables and you might not
    get exactly the virtual methods you expected.

    Python is more laid back about these things. The object itself already
    exists when __init__ is first called. It already has a type, which
    (unlike C++) isn't going to change part way through. All that is missing
    are a few attributes, and if you try to access them too soon you'll get an
    exception rather than a random value.

    It makes sense therefore to give the programmer the scope to override the
    expected sequence of initialisation for those rare cases where it actually
    matters. The programmer also gets enough scope to shoot themselves in the
    foot, but Python programmers are expected to be intelligent enough not to
    do that accidentally.

    Usually though, if a subclass doesn't immediately call the base class
    constructors as the first thing it does in __init__ it indicates poor code
    and should be refactored.

    BTW, the same arguments apply to destructors: if you have a __del__ method
    and need to call the base __del__ methods you have to do that manually as
    well.


    From your Tue Apr 25 13:41:56 2006
    From: your (your)
    Date: 25 Apr 2006 04:41:56 -0700
    Subject: Accessing Parallel Port in Python Error : Priviledged Instruction
    References: <1129344902.717940.57730@f14g2000cwb.googlegroups.com>
    Message-ID: <444e0b04@darkstar>

    type your message here
  • Bruno at Apr 25, 2006 at 11:52 am
    Duncan Booth wrote:
    (snip)
    Usually though, if a subclass doesn't immediately call the base class
    constructors as the first thing it does in __init__ it indicates poor code
    and should be refactored.
    Not necessarily. It's a common case to have some computations to do/some
    attributes to set in the derived class's __init__ before calling the
    superclass's.

    --
    bruno desthuilliers
    python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
    p in 'onurb at xiludom.gro'.split('@')])"
  • Duncan Booth at Apr 25, 2006 at 12:43 pm

    bruno at modulix wrote:

    Duncan Booth wrote:
    (snip)
    Usually though, if a subclass doesn't immediately call the base class
    constructors as the first thing it does in __init__ it indicates poor
    code and should be refactored.
    Not necessarily. It's a common case to have some computations to
    do/some attributes to set in the derived class's __init__ before
    calling the superclass's.
    I did only say 'usually'. Can you actually think of any good examples where
    you have to set a derived attribute before you can call the base class
    constructor? I can't, which is why I was a bit vague.

    The base class is unlikely to depend on the derived class attributes, and
    unless it does there should be no reason which you can't just call the base
    __init__ straight away. Perhaps if the base __init__ calls an overridden
    method, but at that point it sounds to me like something wants refactoring.

    I can think that you might have to do some computations to calculate
    parameters for the base __init__, but that is a separate issue.
  • Bruno at Apr 25, 2006 at 2:56 pm

    Duncan Booth wrote:
    bruno at modulix wrote:

    Duncan Booth wrote:
    (snip)
    Usually though, if a subclass doesn't immediately call the base class
    constructors as the first thing it does in __init__ it indicates poor
    code and should be refactored.
    Not necessarily. It's a common case to have some computations to
    do/some attributes to set in the derived class's __init__ before
    calling the superclass's.

    I did only say 'usually'. Can you actually think of any good examples where
    you have to set a derived attribute before you can call the base class
    constructor?
    class Base(object):
    def __init__(self, arg1):
    self.attr1 = arg1
    self.dothis()

    def dothis(self):
    return self.attr1

    class Derived(Base):
    def __init__(self, arg1, arg2=0):
    self.attr2 = arg2
    Base.__init__(self, arg1)

    def dothis(self):
    return self.attr1 + self.attr2

    (snip)
    Perhaps if the base __init__ calls an overridden
    method, but at that point it sounds to me like something wants refactoring.
    Why so ? This is a well-known pattern (template method). I don't see
    what's wrong with it.
    I can think that you might have to do some computations to calculate
    parameters for the base __init__, but that is a separate issue.

    --
    bruno desthuilliers
    python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
    p in 'onurb at xiludom.gro'.split('@')])"
  • Duncan Booth at Apr 25, 2006 at 5:24 pm

    bruno at modulix wrote:

    class Base(object):
    def __init__(self, arg1):
    self.attr1 = arg1
    self.dothis()

    def dothis(self):
    return self.attr1

    class Derived(Base):
    def __init__(self, arg1, arg2=0):
    self.attr2 = arg2
    Base.__init__(self, arg1)

    def dothis(self):
    return self.attr1 + self.attr2

    (snip)
    Perhaps if the base __init__ calls an overridden
    method, but at that point it sounds to me like something wants
    refactoring.
    Why so ? This is a well-known pattern (template method). I don't see
    what's wrong with it.
    Apart from the fact that you can delete the method 'dothis' from both
    classes with no effect on the code?

    Actually, this is quite an interesting example becaue it wouldn't work in
    C++: if you tried the same trick the call to dothis from the base
    constructor (even assuming it is virtual) would actually call Base.dothis.

    I think you have demonstrated that you can do some things in Python which
    you simply cannot do in static languages like C++: assigning to derived
    attributes before calling a base initialiser, and calling a virtual method
    from a base initialiser. I'm not arguing about that. What I don't have
    though is an example of code where doing this would actually be a good
    thing.

    What I think I'm trying to get at is that I believe that most situations
    where someone actually tries to do something in the base initialiser which
    requires calling a virtual method are probably also cases where the
    initialiser is doing too much: i.e. separating the
    construction/initialisation from actually doing something is usually a good
    idea.
  • Bruno Desthuilliers at Apr 25, 2006 at 11:52 pm

    Duncan Booth a ?crit :
    bruno at modulix wrote:

    class Base(object):
    def __init__(self, arg1):
    self.attr1 = arg1
    self.dothis()

    def dothis(self):
    return self.attr1

    class Derived(Base):
    def __init__(self, arg1, arg2=0):
    self.attr2 = arg2
    Base.__init__(self, arg1)

    def dothis(self):
    return self.attr1 + self.attr2

    (snip)

    Perhaps if the base __init__ calls an overridden
    method, but at that point it sounds to me like something wants
    refactoring.
    Why so ? This is a well-known pattern (template method). I don't see
    what's wrong with it.

    Apart from the fact that you can delete the method 'dothis' from both
    classes with no effect on the code?
    Mmmm... Oh, I see. Agreed, this is not a very good example.
    class Base(object):
    def __init__(self, arg1):
    self.attr1 = arg1
    self.attr42 = self.dothis()
    Is that better ?-)

    Ok, let's be serious now...
    Actually, this is quite an interesting example becaue it wouldn't work in
    C++: if you tried the same trick the call to dothis from the base
    constructor (even assuming it is virtual) would actually call Base.dothis.
    I think you have demonstrated that you can do some things in Python which
    you simply cannot do in static languages like C++: assigning to derived
    attributes before calling a base initialiser, and calling a virtual method
    from a base initialiser. I'm not arguing about that. What I don't have
    though is an example of code where doing this would actually be a good
    thing.
    I don't have any concrete example at hand, but I can tell you I've done
    such things often enough.
    What I think I'm trying to get at is that I believe that most situations
    where someone actually tries to do something in the base initialiser which
    requires calling a virtual method
    I'm afraid I fail to see what's so special about 'virtual' methods - and
    FWIW, since all methods in Python are virtual, if you don't want to call
    virtual methods in the initializer, you won't get very far !-)
    are probably also cases where the
    initialiser is doing too much: i.e. separating the
    construction/initialisation from actually doing something is usually a good
    idea.
    What if some of the things one have to do at initialization is also used
    elsewhere ? You would not duplicate code, would you ?
  • Brian van den Broek at Apr 26, 2006 at 4:06 pm

    Bruno Desthuilliers said unto the world upon 25/04/06 06:52 PM:
    Duncan Booth a ?crit :
    bruno at modulix wrote:


    class Base(object):
    def __init__(self, arg1):
    self.attr1 = arg1
    self.dothis()

    def dothis(self):
    return self.attr1

    class Derived(Base):
    def __init__(self, arg1, arg2=0):
    self.attr2 = arg2
    Base.__init__(self, arg1)

    def dothis(self):
    return self.attr1 + self.attr2

    (snip)


    Perhaps if the base __init__ calls an overridden
    method, but at that point it sounds to me like something wants
    refactoring.
    Why so ? This is a well-known pattern (template method). I don't see
    what's wrong with it.

    Apart from the fact that you can delete the method 'dothis' from both
    classes with no effect on the code?

    Mmmm... Oh, I see. Agreed, this is not a very good example.
    <snip>

    This hobbyist isn't seeing Duncan's point. Wouldn't deleting the
    dothis method from both classes lead to an AttributeError as
    Base.__init__ calls self.dothis()?

    Is the point that one could refactor out the self.dothis() from the
    __init__? Or something else altogether? (I assume it can't be that
    dothis isn't doing real work as it is in the context of a toy example.)

    Enlightenment gratefully received.

    Best to all,

    Brian vdB
  • Bruno at Apr 26, 2006 at 4:46 pm

    Brian van den Broek wrote:
    Bruno Desthuilliers said unto the world upon 25/04/06 06:52 PM:
    Duncan Booth a ?crit :
    (snip)
    Apart from the fact that you can delete the method 'dothis' from both
    classes with no effect on the code?
    Mmmm... Oh, I see. Agreed, this is not a very good example.
    <snip>

    This hobbyist isn't seeing Duncan's point. Wouldn't deleting the dothis
    method from both classes lead to an AttributeError as Base.__init__
    calls self.dothis()?
    Yes, of course. But Duncan (implicitely) meant "deleting the method
    *and* the calls to the method".

    The point is that dothis() returns a value (that is not used), and
    doesn't modify the state of self.

    Or at least, this what *I* understood.
    Is the point that one could refactor out the self.dothis() from the
    __init__? Or something else altogether? (I assume it can't be that
    dothis isn't doing real work as it is in the context of a toy example.)
    Seems like you are assuming too much !-)


    --
    bruno desthuilliers
    python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
    p in 'onurb at xiludom.gro'.split('@')])"
  • Alex Martelli at Apr 26, 2006 at 4:15 am
    Duncan Booth wrote:
    ...
    Actually, this is quite an interesting example becaue it wouldn't work in
    C++: if you tried the same trick the call to dothis from the base
    constructor (even assuming it is virtual) would actually call Base.dothis. Yep.
    I think you have demonstrated that you can do some things in Python which
    you simply cannot do in static languages like C++: assigning to derived
    attributes before calling a base initialiser, and calling a virtual method
    from a base initialiser. I'm not arguing about that. What I don't have
    though is an example of code where doing this would actually be a good
    thing.
    A recognized idiom/pattern in C++ or Java is known as "two-phase
    construction" (yes, there's a two-phase destruction counterpart): have
    minimal, near-empty constructors, then a separate virtual Init method
    which does the actual construction work (often with a framework or at
    least a factory to ensure that Init gets in fact called).

    Each use case of this idiom/pattern relies on virtual methods (most
    generally in a Template Method design pattern) at initialization.

    E.g.: build a composite window by iteratively building subwindows
    (including decorators) as enumerated by a virtual method. Initialize a
    database-connection object by delegating some parts (such as connection,
    local or over the net, and authentication, etc etc) to virtual methods.
    And so on, and so forth.

    What I think I'm trying to get at is that I believe that most situations
    where someone actually tries to do something in the base initialiser which
    requires calling a virtual method are probably also cases where the
    initialiser is doing too much: i.e. separating the
    construction/initialisation from actually doing something is usually a good
    idea.
    But why should that be? Template Method is perhaps the MOST generally
    useful design pattern -- why would it be any less useful in
    initialization than elsewhere?!


    Alex
  • Duncan Booth at Apr 26, 2006 at 7:44 am

    Alex Martelli wrote:

    What I think I'm trying to get at is that I believe that most
    situations where someone actually tries to do something in the base
    initialiser which requires calling a virtual method are probably also
    cases where the initialiser is doing too much: i.e. separating the
    construction/initialisation from actually doing something is usually
    a good idea.
    But why should that be? Template Method is perhaps the MOST generally
    useful design pattern -- why would it be any less useful in
    initialization than elsewhere?!
    Because it is error prone?

    Any method which is called from the constructor/initialiser has to operate
    correctly on an object which at that point is not fully
    constructed/initialised. So instead of having to write a method on a Foo
    object, your template method has to operate on a partial Foo. The danger is
    that you haven't clearly defined the partial Foo interface sufficiently and
    the method tries to use other parts of the object which haven't yet been
    set up. That situation gets worse when you have a class hierarchy as the
    subclass needs to know that it has to do complete its own initialisation
    before constructing the base class instead of afterwards, and if you are
    going to document that requirement, why not do it properly and split the
    construction in two?

    That's why I would go for the 2-phase construction: after the first phase
    you have an object which is fully initialised, just not yet
    used/connected/running. For example httplib.HTTPConnection does this: you
    construct the object with a host and port, but the actual connection is
    triggered by a separate object.
    I would suggest your example of a database connection belongs in that
    category: it should have an initial unconnected idle state and a separate
    connection.

    I think your example of a composite window building subwindows is the sort
    of use case I was asking for: it does sound tempting to construct the
    window and all its subwindows together. I'm happy to concede on that one.
  • Bruno at Apr 26, 2006 at 9:36 am

    Duncan Booth wrote:
    Alex Martelli wrote:

    What I think I'm trying to get at is that I believe that most
    situations where someone actually tries to do something in the base
    initialiser which requires calling a virtual method are probably also
    cases where the initialiser is doing too much: i.e. separating the
    construction/initialisation from actually doing something is usually
    a good idea.
    But why should that be? Template Method is perhaps the MOST generally
    useful design pattern -- why would it be any less useful in
    initialization than elsewhere?!
    Because it is error prone?
    Programming *is* error prone.
    Any method which is called from the constructor/initialiser has to operate
    correctly
    any method has to operate correctly anyway !-)
    on an object which at that point is not fully
    constructed/initialised.
    In Python, when the __init__ method is called, the object is at least
    fully constructed.
    So instead of having to write a method on a Foo
    object, your template method has to operate on a partial Foo. The danger is
    that you haven't clearly defined the partial Foo interface sufficiently and
    the method tries to use other parts of the object which haven't yet been
    set up.
    If so, the worse thing that can happen is an exception - and you'll
    surely spot the problem really soon.
    That situation gets worse when you have a class hierarchy as the
    subclass needs to know that it has to do complete its own initialisation
    before constructing the base class instead of afterwards, and if you are
    going to document that requirement, why not do it properly and split the
    construction in two?
    It's *already* split : __new__ construct the object, __init__ initialize it.
    That's why I would go for the 2-phase construction:
    But that's already what you have.
    after the first phase
    you have an object which is fully initialised, just not yet
    used/connected/running. For example httplib.HTTPConnection does this: you
    construct the object with a host and port, but the actual connection is
    triggered by a separate object.
    If you look at file objects, they do try and open the file at init time.
    Is a net or db connection that different ?

    (snip)

    --
    bruno desthuilliers
    python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
    p in 'onurb at xiludom.gro'.split('@')])"
  • Duncan Booth at Apr 26, 2006 at 10:22 am

    bruno at modulix wrote:

    It's *already* split : __new__ construct the object, __init__
    initialize it.
    That's why I would go for the 2-phase construction:
    But that's already what you have.
    Very good point.
    after the first phase
    you have an object which is fully initialised, just not yet
    used/connected/running. For example httplib.HTTPConnection does this:
    you construct the object with a host and port, but the actual
    connection is triggered by a separate object.
    If you look at file objects, they do try and open the file at init
    time. Is a net or db connection that different ?
    Well, yes, since the whole point is that we are discussing overriding
    methods and I bet you haven't subclassed Python file objects recently.

    For network or database connections you do want to supply your own
    handlers for things like authentication.
  • Bruno at Apr 26, 2006 at 11:05 am

    Duncan Booth wrote:
    bruno at modulix wrote:

    It's *already* split : __new__ construct the object, __init__
    initialize it.
    That's why I would go for the 2-phase construction:
    But that's already what you have.
    Very good point.

    after the first phase
    you have an object which is fully initialised, just not yet
    used/connected/running. For example httplib.HTTPConnection does this:
    you construct the object with a host and port, but the actual
    connection is triggered by a separate object.
    If you look at file objects, they do try and open the file at init
    time. Is a net or db connection that different ?

    Well, yes, since the whole point is that we are discussing overriding
    methods and I bet you haven't subclassed Python file objects recently.
    And you win !-)

    Anyway, I didn't suggest that opening a connection to whatever should be
    done in the __init__ - I just wanted to point that acquiring a resource
    in the initializer (and freeing it in the finalizer) can sometimes be
    perfectly sensible.

    wrt/ initializer as a template method, I still fail to see why this
    should be a problem. The fact that one should avoid doing anything else
    than initialization in the initializer is just plain old common sense
    IMHO - the use of calls to other methods that can possibly be overriden
    in a subclass is orthogonal. And if the guy writing the subclass do
    stupid things when overridding these methods, well, too bad for him -
    but as the author of the base class, that's definitively not my problem
    (given proper documentation of course)

    Trying to protect stupid programmers from doing stupid things is a total
    waste of time anyway.

    --
    bruno desthuilliers
    python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
    p in 'onurb at xiludom.gro'.split('@')])"
  • Carl Banks at Apr 26, 2006 at 9:40 am

    Duncan Booth wrote:
    Alex Martelli wrote:
    What I think I'm trying to get at is that I believe that most
    situations where someone actually tries to do something in the base
    initialiser which requires calling a virtual method are probably also
    cases where the initialiser is doing too much: i.e. separating the
    construction/initialisation from actually doing something is usually
    a good idea.
    But why should that be? Template Method is perhaps the MOST generally
    useful design pattern -- why would it be any less useful in
    initialization than elsewhere?!
    Because it is error prone?

    Any method which is called from the constructor/initialiser has to operate
    correctly on an object which at that point is not fully
    constructed/initialised. So instead of having to write a method on a Foo
    object, your template method has to operate on a partial Foo. The danger is
    that you haven't clearly defined the partial Foo interface sufficiently and
    the method tries to use other parts of the object which haven't yet been
    set up.
    In Python, if you try to use an uninitialized member you get an
    AttributeError; I really don't see too much inherent danger here. If
    you make a mistake, the language tells you and you fix it. C++ and
    Java are worse since accessing uninitialized variables is a silent
    mistake, so it makes sense to avoid that kind thing in those languages.

    Carl Banks
  • Carl Banks at Apr 25, 2006 at 12:33 pm

    cctv.star at gmail.com wrote:
    Heiko Wundram wrote:
    Because sometimes you don't want to call the base classes constructors?
    Sounds strange to me at the moment, but I'll try to adjust to this
    thought.
    In Java and C++, classes have private members that can only be accessed
    by the class itself (and, in C++, friends). In those languages, a base
    constructor needs to be called to initialize the base class's private
    members.

    Python has no private members (except for the double underscore
    thingies, which aren't that common). Unlike C++ and Java, the derived
    class's __init__ can usually initialize all the base class's members,
    and it's occasionally useful to do so.

    I would agree it's a mistake to not call the base class's __init__
    unless you're doing it deliberately. If you want a tool to catch those
    mistakes, have a look at pychecker. It can inform you whenever the
    base class __init__ is not called.

    (However, I totally disagree that it's a good idea to always call it
    first, though. I've written base class __init__s that expected the
    subclass to provide initialization methods, and some of those methods
    needed some subclass members to exist before they were called.)
  • Bruno at Apr 25, 2006 at 11:55 am

    cctv.star at gmail.com wrote:
    I was wondering, why you always have to remember to call bases'
    constructors
    <pedantic>
    s/constructors/__init__/

    the __init__() method is *not* the constructor. Object's instanciation
    is a two-stage process: __new__() is called first, then __init__().
    </pedantic>

    --
    bruno desthuilliers
    python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
    p in 'onurb at xiludom.gro'.split('@')])"
  • Carl Banks at Apr 25, 2006 at 12:45 pm

    bruno at modulix wrote:
    cctv.star at gmail.com wrote:
    I was wondering, why you always have to remember to call bases'
    constructors
    <pedantic>
    s/constructors/__init__/

    the __init__() method is *not* the constructor. Object's instanciation
    is a two-stage process: __new__() is called first, then __init__().
    </pedantic>
    You know, Python's __init__ has almost the same semantics as C++
    constructors (they both initialize something that's already been
    allocated in memory, and neither can return a substitute object). I
    actually think constructors are misnamed in C++, they should be called
    initializers (and destructors finalizers). The only thing is that C++
    doesn't always call operator new when constructing objects, whereas
    Python always calls __new__, so you can put some initialization in
    __new__ if you want.

    Other than that I'd say that Python __init__ is analogous to Java and
    C++ constructors, but is not a constructor because C++ and Java
    constructors are not constructors. :) And Java has pointers, not
    references. :)

    A-rose-by-any-other-name-ly yr's,

    Carl Banks
  • Duncan Booth at Apr 25, 2006 at 1:25 pm

    Carl Banks wrote:

    You know, Python's __init__ has almost the same semantics as C++
    constructors (they both initialize something that's already been
    allocated in memory, and neither can return a substitute object).
    There is a significant difference: imagine B is a base type and C a
    subclass of B:

    When you create an object of type C in Python, while B.__init__ is
    executing self is an object of type C (albeit without all the attributes
    you expect on your C).

    In C++ when the B() constructor is executing the object is an object of
    type B. It doesn't become a C object until the C() constructor is
    executing.

    In other words, the object is constructed in Python before any __init__ is
    called, but in C++ it isn't constructed until after all the base class
    constructors have returned.
  • Carl Banks at Apr 25, 2006 at 2:42 pm

    Duncan Booth wrote:
    In other words, the object is constructed in Python before any __init__ is
    called, but in C++ it isn't constructed until after all the base class
    constructors have returned.
    That's true. Good point.


    Carl Banks
  • Lawrence D'Oliveiro at Apr 27, 2006 at 7:40 am
    In article <Xns97B092B9B6512duncanbooth at 127.0.0.1>,
    Duncan Booth wrote:
    Carl Banks wrote:
    You know, Python's __init__ has almost the same semantics as C++
    constructors (they both initialize something that's already been
    allocated in memory, and neither can return a substitute object).
    There is a significant difference: imagine B is a base type and C a
    subclass of B:

    When you create an object of type C in Python, while B.__init__ is
    executing self is an object of type C (albeit without all the attributes
    you expect on your C).

    In C++ when the B() constructor is executing the object is an object of
    type B. It doesn't become a C object until the C() constructor is
    executing.

    In other words, the object is constructed in Python before any __init__ is
    called, but in C++ it isn't constructed until after all the base class
    constructors have returned.
    But if "construction" is what a constructor does, then you're wrong.
  • Duncan Booth at Apr 27, 2006 at 8:23 am

    Lawrence D'Oliveiro wrote:

    In other words, the object is constructed in Python before any
    __init__ is called, but in C++ it isn't constructed until after all
    the base class constructors have returned.
    But if "construction" is what a constructor does, then you're wrong.
    I may be wrong (my C++ is getting rusty), but my belief is that if you have
    a base class B and a derived class D, then until the B() constructor has
    returned, the type of the object (as indicated by RTTI or by calling
    virtual methods) is a B. It isn't until after the B constructor has
    returned that the object is changed into a D.

    This is different from Python's behaviour where the object is created as
    its final type and then initialised.
  • Lawrence D'Oliveiro at Apr 27, 2006 at 7:41 am
    In article <1145969107.837185.212970 at e56g2000cwe.googlegroups.com>,
    "Carl Banks" wrote:
    bruno at modulix wrote:
    cctv.star at gmail.com wrote:
    I was wondering, why you always have to remember to call bases'
    constructors
    <pedantic>
    s/constructors/__init__/

    the __init__() method is *not* the constructor. Object's instanciation
    is a two-stage process: __new__() is called first, then __init__().
    </pedantic>
    You know, Python's __init__ has almost the same semantics as C++
    constructors (they both initialize something that's already been
    allocated in memory, and neither can return a substitute object). I
    actually think constructors are misnamed in C++, they should be called
    initializers (and destructors finalizers).
    "Constructor" is also the term used for the corresponding method in Java.

    Is there any OO language that does not use "constructor" in this sense?
    I don't think there is one. This is standard OO terminology.
  • Carl Banks at Apr 27, 2006 at 8:38 am

    Lawrence D'Oliveiro wrote:
    In article <1145969107.837185.212970 at e56g2000cwe.googlegroups.com>,
    "Carl Banks" wrote:
    bruno at modulix wrote:
    cctv.star at gmail.com wrote:
    I was wondering, why you always have to remember to call bases'
    constructors
    <pedantic>
    s/constructors/__init__/

    the __init__() method is *not* the constructor. Object's instanciation
    is a two-stage process: __new__() is called first, then __init__().
    </pedantic>
    You know, Python's __init__ has almost the same semantics as C++
    constructors (they both initialize something that's already been
    allocated in memory, and neither can return a substitute object). I
    actually think constructors are misnamed in C++, they should be called
    initializers (and destructors finalizers).
    "Constructor" is also the term used for the corresponding method in Java.

    Is there any OO language that does not use "constructor" in this sense?
    I don't think there is one. This is standard OO terminology.
    Python?

    Yeah, I realize it's common terminology, but I just think it's a poor
    name. That Python doesn't really call __init__ a constructor is good
    (I guess it doesn't really call it anything but __init__), because
    constructor would be a bad name for it.


    Carl Banks
  • Bruno at Apr 27, 2006 at 9:07 am

    Lawrence D'Oliveiro wrote:
    In article <1145969107.837185.212970 at e56g2000cwe.googlegroups.com>,
    "Carl Banks" wrote:

    bruno at modulix wrote:
    cctv.star at gmail.com wrote:
    I was wondering, why you always have to remember to call bases'
    constructors
    <pedantic>
    s/constructors/__init__/

    the __init__() method is *not* the constructor. Object's instanciation
    is a two-stage process: __new__() is called first, then __init__().
    </pedantic>
    You know, Python's __init__ has almost the same semantics as C++
    constructors (they both initialize something that's already been
    allocated in memory, and neither can return a substitute object). I
    actually think constructors are misnamed in C++, they should be called
    initializers (and destructors finalizers).

    "Constructor" is also the term used for the corresponding method in Java.

    Is there any OO language that does not use "constructor" in this sense?
    Smalltalk. Just like Python, it has constructor *and* initializer.
    I don't think there is one. This is standard OO terminology.
    Being "standard" doesn't imply it's accurate.

    --
    bruno desthuilliers
    python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
    p in 'onurb at xiludom.gro'.split('@')])"

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouppython-list @
categoriespython
postedApr 25, '06 at 10:34a
activeApr 27, '06 at 9:07a
posts32
users11
websitepython.org

People

Translate

site design / logo © 2022 Grokbase