Re: Inheritance problem

2008-11-05 Thread Diez B. Roggisch
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

2008-11-05 Thread Mr . SpOOn
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

2007-05-09 Thread Neil Cerutti
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

2007-05-09 Thread Bjoern Schliessmann
[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

2007-05-09 Thread attn . steven . kuo
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

2007-05-09 Thread Jason
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?

2006-01-06 Thread Simon Percivall
Don't use self.__class__, use the name of the class.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Inheritance problem?

2006-01-06 Thread Pierre Barbier de Reuille
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?

2006-01-06 Thread Xavier Morel
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?

2006-01-06 Thread Pierre Barbier de Reuille
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?

2006-01-06 Thread Xavier Morel
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?

2006-01-06 Thread Mike Meyer
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?

2006-01-06 Thread KraftDiner
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?

2006-01-06 Thread Pierre Barbier de Reuille
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?

2006-01-06 Thread Scott David Daniels
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 ?

2005-08-24 Thread db
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 ?

2005-08-24 Thread jitya
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 ?

2005-08-24 Thread tooper
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 ?

2005-08-24 Thread jitya
The stuff on Descriptor.htm was really good . 

 Thanks

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Inheritance problem ?

2005-08-24 Thread tooper
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

2004-12-03 Thread Dan Perl
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

2004-12-02 Thread Greg Ewing
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

2004-12-02 Thread Dan Perl
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