Alex Hall wrote:
On 10/21/11, Steven D'Aprano <st...@pearwood.info> wrote:
[...]
The one exception to this is if your class changes the method signature.
E.g. if A.method takes no arguments, but B.method requires an argument.
super cannot help you now. But changing the signature of methods is
almost always the wrong thing to do: it is a violation of good object
oriented design, and should be avoided. The main time it is justified is
in the class constructor methods, __new__ or __init__, in which case you
may need to avoid super and *carefully* manage the inheritance by hand.

I'm not sure about this part. Could I not simply do something like:
class a(object):
 def m(self, p1): pass

class b(a):
 def m(self, p1, p2, *args, **kwords):
  super(b, self).m(*args, **kwords) #different signatures, but a.m()
still gets what it wants, if called correctly

No, that won't work. Consider what happens when you do this:


instance = b()
instance.m(1, 2, "spam", "ham", foo=None)

The m method gets called with arguments:

p1 = 1
p2 = 2
args = ("spam", "ham")
kwords = {"foo": None}


So far so good. But b.m calls a.m using:

super(b, self).m(*args, **kwords)

which drops p1=1 completely, replacing it with "spam". That surely is incorrect. It also tries to supply an extra two arguments, "ham" and foo=None, but a.m only takes one argument.


Also, what is the difference between __init__ (what I always use) and
__new__? If you can change these, why not other methods? Of course
these would be the most commonly changed, but the question stands.

__new__ and __init__ are respectively the constructor and initialiser for the class.

__new__ is responsible for actually creating the instance, and returning it. If the class is immutable, like int, str or tuple, this is the time to set the contents of the instance. (Once the instance is created, it's too late to change it.) Normally, you don't need to do anything with __new__, you can consider it a moderately specialised method.

__init__ is responsible for initialising any extra attributes on the instance, or for mutable classes like lists or dicts, setting the contents. It's much more common to use __init__ rather than __new__.


--
Steven

_______________________________________________
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Reply via email to