Re: Inheritance problem
Mr.SpOOn wrote: Hi, I have a problem with this piece of code: class NoteSet(OrderedSet): def has_pitch(self): pass def has_note(self): pass class Scale(NoteSet): def __init__(self, root, type): self.append(root) self.type = type ScaleType(scale=self) OrderedSet is an external to use ordered sets. And it has an append method to append elements to the set. When I try to create a Scale object: s = Scale(n, '1234567') # n is a note I get this error: Traceback (most recent call last): File notes.py, line 276, in module s = Scale(n, '1234567') File notes.py, line 243, in __init__ self.append(root) File ordered_set.py, line 78, in append self._insertatnode(self._end.prev, element) AttributeError: 'Scale' object has no attribute '_end' I can't understand where the error is. Can you help me? You need to call the __init__ of NoteSet inside Scale, as otherwise the instance isn't properly initialized. class Scale(NoteSet): def __init__(self, root, type): super(Scale, self).__init__() ... or NoteSet.__init__(self) if you have an old-style class. Diez -- http://mail.python.org/mailman/listinfo/python-list
Re: Inheritance problem
On Wed, Nov 5, 2008 at 6:59 PM, Diez B. Roggisch [EMAIL PROTECTED] wrote: You need to call the __init__ of NoteSet inside Scale, as otherwise the instance isn't properly initialized. Thanks, solved. -- http://mail.python.org/mailman/listinfo/python-list
Re: Inheritance problem
On 2007-05-09, [EMAIL PROTECTED] [EMAIL PROTECTED] wrote: I'm trying to solve a problem using inheritance and polymorphism in python 2.4.2 It's not an inheritance problem, it's a notation problem. Python uses explicit 'self', saving you the trouble of devising a naming convention for data members. I think it's easier to explain the problem using simple example: class shortList: def __init__(self): self.setList() def setList(self): a = [1,2,3] print a You need to use self.a = [1, 2, 3] print self.a The notation you used creates a local variable, but you need a data member. class longList(shortList): def __init__(self): shortList.setList() self.setList() def setList(self): a.extend([4,5,6]) print a Similarly: self.a.extend([4, 5, 6]) print self.a Does that give you better results? -- Neil Cerutti If we stay free of injuries, we'll be in contention to be a healthy team. --Chris Morris -- http://mail.python.org/mailman/listinfo/python-list
Re: Inheritance problem
[EMAIL PROTECTED] wrote: class longList(shortList): def __init__(self): shortList.setList() self.setList() Addition: Always call the base class __init__ in your constructor if there exists one, i. e. class longList(shortList) def __init__(self): shortlist.__init__() # [...] Regards, Björn -- BOFH excuse #108: The air conditioning water supply pipe ruptured over the machine room -- http://mail.python.org/mailman/listinfo/python-list
Re: Inheritance problem
On May 9, 11:33 am, Bjoern Schliessmann usenet- [EMAIL PROTECTED] wrote: [EMAIL PROTECTED] wrote: class longList(shortList): def __init__(self): shortList.setList() self.setList() Addition: Always call the base class __init__ in your constructor if there exists one, i. e. class longList(shortList) def __init__(self): shortlist.__init__() # [...] Delegating to an ancestor class by calling an unbound method is fine as long as one remembers to pass an instance as the first argument. So, this means: shortList.setList(self) and shortList.__init__(self) for the examples above. -- Regards, Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Inheritance problem
On May 9, 12:09 pm, [EMAIL PROTECTED] wrote: I'm trying to solve a problem using inheritance and polymorphism in python 2.4.2 I think it's easier to explain the problem using simple example: class shortList: def __init__(self): self.setList() def setList(self): a = [1,2,3] print a class longList(shortList): def __init__(self): shortList.setList() self.setList() def setList(self): a.extend([4,5,6]) print a def main(): a = raw_input('Do you want short or long list? (s/l)') if a.upper() == 'S': lst = shortList() else: lst = longList() lst.setList() if __name__ == '__main__': main() After that I'm getting a message: TypeError: unbound method setList() must be called with shortList instance as first argument (got nothing instead) Where is the problem? Thanks in advance... As Neil indicated, you use the self object to access the current object's class members. The first parameter to a Python method is the object that the method is operating on. For a silly example: class SayHi(object): ... def __init__(self, name): ... self.name = name # Save the name for later ... def Talk(self): ... print Hi,, self.name ... helloWorld = SayHi(World) helloWorld.Talk() Hi, World As you can see, the __init__ special method saves the name by self.name = name. Similarly, the name is accessed in the Talk method via self.name. Please note that the first parameter is called self by convention. Python doesn't care what you call the first parameter to a method. However, most of the Python world uses self, so it is highly recommended to follow this convention. Now for the problem specific to the error message that you're getting: As above, the first parameter to a Python method is the object being operated on. Python uses a little bit of syntactic sugar to make calling methods easier. You can explicitly call a class method directly and pass the object in as the first parameter yourself. helloWorld.Talk() # This is the normal way of calling Talk Hi, World SayHi.Talk(helloWorld) # This works, too! Hi, World To easily call a superclass method, you can explicitly use the baseclass. You're attempting to do so, but you forgot one important ingrediant: the object being operated on! In C++, the object is implicit. In Python, you must explicitly send it to the superclass: class SayHello(SayHi): ... def __init__(self, name): ... SayHi.__init__(self, name) # Call the superclass's init ... def Talk(self): ... print Hello,, self.name ... moreTalk = SayHello(World) moreTalk.Talk() Hello, World Basically, you need to: 1. Assign your lists in setList to self.a instead of the local variable a. 2. Pass the object to the superclass method in setList (shortList.setList(self)) There are other things that may be improved with your design. Keep plugging at it! --Jason -- http://mail.python.org/mailman/listinfo/python-list
Re: Inheritance problem?
Don't use self.__class__, use the name of the class. -- http://mail.python.org/mailman/listinfo/python-list
Re: Inheritance problem?
Well, I would even add : don't use super ! Just call the superclass method : MyClass.__init__(self) Simon Percivall a écrit : Don't use self.__class__, use the name of the class. -- http://mail.python.org/mailman/listinfo/python-list
Re: Inheritance problem?
Pierre Barbier de Reuille wrote: Well, I would even add : don't use super ! Just call the superclass method : MyClass.__init__(self) Simon Percivall a écrit : Don't use self.__class__, use the name of the class. Bad idea if you're using new-style classes with a complex inheritance hierarchy and multiple inheritance. -- http://mail.python.org/mailman/listinfo/python-list
Re: Inheritance problem?
Xavier Morel a écrit : Pierre Barbier de Reuille wrote: Well, I would even add : don't use super ! Just call the superclass method : MyClass.__init__(self) Simon Percivall a écrit : Don't use self.__class__, use the name of the class. Bad idea if you're using new-style classes with a complex inheritance hierarchy and multiple inheritance. As a reference : http://fuhm.org/super-harmful/ I may say this is the only place I ever saw what super *really* is for. The behavior is far too complex and misthought. All I can say is : don't use it ! It solves *nothing* and creates too many bugs in the long run. -- http://mail.python.org/mailman/listinfo/python-list
Re: Inheritance problem?
Pierre Barbier de Reuille wrote: Xavier Morel a écrit : Pierre Barbier de Reuille wrote: Well, I would even add : don't use super ! Just call the superclass method : MyClass.__init__(self) Simon Percivall a écrit : Don't use self.__class__, use the name of the class. Bad idea if you're using new-style classes with a complex inheritance hierarchy and multiple inheritance. As a reference : http://fuhm.org/super-harmful/ I may say this is the only place I ever saw what super *really* is for. The behavior is far too complex and misthought. All I can say is : don't use it ! It solves *nothing* and creates too many bugs in the long run. My own encounter with the subject was Guido's Unifying types and classes in Python 2.2 (http://www.python.org/2.2.3/descrintro.html#mro for the part on super itself), but I'll keep your link close by. -- http://mail.python.org/mailman/listinfo/python-list
Re: Inheritance problem?
Xavier Morel [EMAIL PROTECTED] writes: Pierre Barbier de Reuille wrote: Well, I would even add : don't use super ! Just call the superclass method : MyClass.__init__(self) Simon Percivall a écrit : Don't use self.__class__, use the name of the class. Bad idea if you're using new-style classes with a complex inheritance hierarchy and multiple inheritance. To quote the original code: class MyClass(MyBaseClass) def __init__(self) super(self.__class__, self).__init__() self.type = MyClassType return self class MySpecialClass(MyClass) def __init__(self) super(self.__class__, self).__init__() self.type = MySpecialClassType return self The only place it uses self.__class__ is in the calls to super. Super finds the superclass of it's first argument. If that argument is self.__class__, then super will always return the superclass of the class of self, *not* the superclass of the class who's code is being run. That's why the code resuls in an infinite recursion. And a note to the OP: __init__'s return value is ignored. You should delete the return self from your methods. mike -- Mike Meyer [EMAIL PROTECTED] http://www.mired.org/home/mwm/ Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information. -- http://mail.python.org/mailman/listinfo/python-list
Re: Inheritance problem?
So ok I've written a piece of code that demonstrates the problem. Can you suggest how I change the Square class init? class Shape(object): def __init__(self): print 'MyBaseClass __init__' class Rectangle(Shape): def __init__(self): super(self.__class__, self).__init__() self.type = Rectangle print 'Rectangle' class Square(Rectangle): def __init__(self): super(self.__class__, self).__init__() self.type = Square print 'Square' r = Rectangle() s = Square() -- http://mail.python.org/mailman/listinfo/python-list
Re: Inheritance problem?
KraftDiner a écrit : So ok I've written a piece of code that demonstrates the problem. Can you suggest how I change the Square class init? class Shape(object): def __init__(self): print 'MyBaseClass __init__' class Rectangle(Shape): def __init__(self): super(self.__class__, self).__init__() self.type = Rectangle print 'Rectangle' class Square(Rectangle): def __init__(self): super(self.__class__, self).__init__() self.type = Square print 'Square' r = Rectangle() s = Square() I suggest you have a look at the link I gave before : http://fuhm.org/super-harmful/ It gives a good explanation about what happens with super. At least, if you *really* want to use it, change your code like that : class Shape(object): def __init__(self): super(Shape, self).__init__() print 'Shape __init__' class Rectangle(Shape): def __init__(self): super(Rectangle, self).__init__() self.type = Rectangle print 'Rectangle' class Square(Rectangle): def __init__(self): super(Square, self).__init__() self.type = Square print Square r = Rectangle() s = Square() But, once more, I would recommand to use direct method call Pierre -- http://mail.python.org/mailman/listinfo/python-list
Re: Inheritance problem?
KraftDiner wrote: So ok I've written a piece of code that demonstrates the problem. Can you suggest how I change the Square class init? class Shape(object): def __init__(self): print 'MyBaseClass __init__' class Rectangle(Shape): def __init__(self): # super(self.__class__, self).__init__() super(Rectangle, self).__init__()# XXX fixed self.type = Rectangle print 'Rectangle' class Square(Rectangle): def __init__(self): # super(self.__class__, self).__init__() super(Square, self).__init__()# XXX fixed self.type = Square print 'Square' r = Rectangle() s = Square() -- -Scott David Daniels [EMAIL PROTECTED] -- http://mail.python.org/mailman/listinfo/python-list
Re: Inheritance problem ?
On Wed, 24 Aug 2005 03:34:36 -0700, tooper wrote: Hello all, I'm trying to implement a common behavior for some object that can be read from a DB or (when out of network) from an XML extract of this DB. I've then wrote 2 classes, one reading from XML the other from the DB, both inheritating from a common one where I want to implement several common methods. Doing this, I've come to some behaviour I can't explain to myself, which I've reproduced in the example bellow : - class myfather: def __repr__(self): return \t a=+self.a+\n\t b=+self.b class mychilda(myfather): def __init__(self,a): self.a= a def __getattr__(self,name): return Undefined for mychilda class mychildb(myfather): def __init__(self,b): self.b= b def __getattr__(self,name): return Undefined for mychildb a= mychilda(a) b= mychildb(b) print a:\n+str(a) print b:\n+str(b) - I was expecting to get : a: a= a b= Undefined for mychilda b: a= Undefined for mychildb b= b but I get the following error : File /home/thierry/mytest.py, line 20, in ? print a:\n+str(a) TypeError: 'str' object is not callable Could someone explain me what I missed ? Thanks in advance ! try new style classes. class myfather(object): see http://users.rcn.com/python/download/Descriptor.htm HTH Arjen -- http://mail.python.org/mailman/listinfo/python-list
Re: Inheritance problem ?
tooper wrote: Hello all, I'm trying to implement a common behavior for some object that can be read from a DB or (when out of network) from an XML extract of this DB. I've then wrote 2 classes, one reading from XML the other from the DB, both inheritating from a common one where I want to implement several common methods. Doing this, I've come to some behaviour I can't explain to myself, which I've reproduced in the example bellow : - class myfather: def __repr__(self): return \t a=+self.a+\n\t b=+self.b class mychilda(myfather): def __init__(self,a): self.a= a def __getattr__(self,name): return Undefined for mychilda class mychildb(myfather): def __init__(self,b): self.b= b def __getattr__(self,name): return Undefined for mychildb a= mychilda(a) b= mychildb(b) print a:\n+str(a) print b:\n+str(b) - I was expecting to get : a: a= a b= Undefined for mychilda b: a= Undefined for mychildb b= b but I get the following error : File /home/thierry/mytest.py, line 20, in ? print a:\n+str(a) TypeError: 'str' object is not callable Could someone explain me what I missed ? Thanks in advance ! hi I am got python 2.4 and changed class myfather to new style classes class myfather(object) it worked. here is the output : a: a=a b=Undefined for mychilda b: a=Undefined for mychildb b=b But i myself still need explaination ;) regards jitu -- http://mail.python.org/mailman/listinfo/python-list
Re: Inheritance problem ?
Thanks, at least makes it running ! I'll have to teach myself to move to this new style classes by default anyway... -- http://mail.python.org/mailman/listinfo/python-list
Re: Inheritance problem ?
The stuff on Descriptor.htm was really good . Thanks -- http://mail.python.org/mailman/listinfo/python-list
Re: Inheritance problem ?
Not always easy to follow but great ! Using __str__ instead of __repr__ makes it work also with old style (thanks to Simon Brunning for suggesting it, and with your link I even now understand why !) -- http://mail.python.org/mailman/listinfo/python-list
Re: inheritance problem with 2 cooperative methods
This is almost the same code as Greg's with the only difference being that test for configuration having been done. But the test is unnecessary. I don't see how setConfig could be invoked in the super of the base class (A), so such a test would be relevant only in subclasses, if they DO invoke setConfig. But it's better if they just don't invoke it, which makes for a much cleaner solution. Thanks anyway. BTW, you named the attribute configinitialized in one place and configSet in the other place. Which proves that the test is redundant, because it does work anyway as is. I had a similar solution, where I was invoking setConfig only if the class of self is the same as the class where __init__ is defined, something like this: class A (object): def __init__(self, config): self.x = 0 super(A, self).__init__() if A == self.__class__: self.setConfig(config) I didn't like it though because it has to be done like this in every subclass's __init__. And it's a problem that I didn't realize at the time if a subclass just does not need to override __init__ (then the configuration is just not set). Dan David Fraser [EMAIL PROTECTED] wrote in message news:[EMAIL PROTECTED] What about using an attribute in the base class to remember whether initial config has been done? This seems to work: #!/usr/bin/python class A (object): def __init__(self, config): self.x = 0 self.configinitialized = False super(A, self).__init__() if not self.configinitialized: self.setConfig(config) def setConfig(self, config): self.x += config['x'] self.configset = True class B (A): def __init__(self, config): self.y = 0 super(B, self).__init__(config) def setConfig(self, config): super(B, self).setConfig(config) self.y += config['y'] class C (B): def __init__(self, config): self.z = 0 super(C, self).__init__(config) def setConfig(self, config): super(C, self).setConfig(config) self.z += config['z'] config = {'x':1, 'y':2, 'z':3} alpha = A(config) print alpha.x beta = B(config) print beta.x, beta.y beta.setConfig(config) print beta.x, beta.y gamma = C(config) print gamma.x, gamma.y, gamma.z gamma.setConfig(config) print gamma.x, gamma.y, gamma.z -- http://mail.python.org/mailman/listinfo/python-list
Re: inheritance problem with 2 cooperative methods
Dan Perl wrote: So far, so good! But let's assume that I want to change the __init__ methods so that they take a configuration as an argument so the objects are created and configured in one step, like this: alpha = A(config) One way would be to make the setConfig call only in the root class, and perform the initialisation that it depends on *before* making the super call in each __init__ method, i.e. class A (object): def __init__(self, config): self.x = 0 self.setConfig(config) class B (A): def __init__(self, config): self.y = 0 super(B, self).__init__(config) class C (B): def __init__(self, config): self.z = 0 super(C, self).__init__(config) This works here because each of the initialisation operations is self-contained. It might not work so well in real life if some of the base class state needs to be initialised before the subclass initialisation can be performed. However, it's worth considering -- I came across the same sort of problem several times in PyGUI, and I usually managed to solve it by carefully arranging initialisations before and after the super call. If you can't use that solution, I would suggest you keep the __init__ and setConfig operations separate, and live with having to call setConfig after creating an object. Factory functions could be provided if you were doing this a lot. -- Greg Ewing, Computer Science Dept, University of Canterbury, Christchurch, New Zealand http://www.cosc.canterbury.ac.nz/~greg -- http://mail.python.org/mailman/listinfo/python-list
Re: inheritance problem with 2 cooperative methods
Thank you very much, Greg, that does the job! Somehow I couldn't see it and I needed someone to point out to me. Dan Greg Ewing [EMAIL PROTECTED] wrote in message news:[EMAIL PROTECTED] Dan Perl wrote: So far, so good! But let's assume that I want to change the __init__ methods so that they take a configuration as an argument so the objects are created and configured in one step, like this: alpha = A(config) One way would be to make the setConfig call only in the root class, and perform the initialisation that it depends on *before* making the super call in each __init__ method, i.e. class A (object): def __init__(self, config): self.x = 0 self.setConfig(config) class B (A): def __init__(self, config): self.y = 0 super(B, self).__init__(config) class C (B): def __init__(self, config): self.z = 0 super(C, self).__init__(config) This works here because each of the initialisation operations is self-contained. It might not work so well in real life if some of the base class state needs to be initialised before the subclass initialisation can be performed. However, it's worth considering -- I came across the same sort of problem several times in PyGUI, and I usually managed to solve it by carefully arranging initialisations before and after the super call. If you can't use that solution, I would suggest you keep the __init__ and setConfig operations separate, and live with having to call setConfig after creating an object. Factory functions could be provided if you were doing this a lot. -- Greg Ewing, Computer Science Dept, University of Canterbury, Christchurch, New Zealand http://www.cosc.canterbury.ac.nz/~greg -- http://mail.python.org/mailman/listinfo/python-list