Re: [Tutor] Changing a class into a subclass

2005-03-25 Thread Alan Gauld
  single instance (or indeed no instances because you could
  use a static method... or get really fancy and create a
  meta-class!). 
 
 or make it a static method of Building 

Yes that's actually what I meant, but reading it back it 
sounds like I meant static Factory method Ho hum.

 or get really simple and use a module-level function...

Yeah., but I did say if he wanted to be OOPish.

  class Shack(Building):
 def __init__(self,p1,p2...):
Building.__init__(self,...)
Building.register(self,'Shack', Shack)
...rest of init...
 
 I think you want to register Shack before you ever create one. 

Yeah, you are right. My way you register it every time you 
create an instance. A single registration call right after 
the class definition is probably better.

 or you could probably get tricky and do it in a metaclass...

I would do in Smalltalk but meta classes in Python are somewhere 
that I haven't visited yet! :-)

Alan G.

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Changing a class into a subclass

2005-03-24 Thread Max Noel
On Mar 24, 2005, at 18:07, Ismael Garrido wrote:
Hello.
I have a program that saves/loads to/from XML. I have a main class 
Building, and a subclass House(Building). When I save the code I 
instruct each object to save itself to XML (using ElementTree), so 
House adds itself to the XML tree.
My problem is when I load the XML. Before having subclasses what I did 
was to send the XML object (again in ElementTree) to the object and 
let itself load. Now, with subclasses, if I send the House XML to 
Building I get a Building instance, when I need a House instance.
	You can't make an object transform into an object of a different 
class. You need to identify what class the object will be an instance 
of before loading it. Which, if you're using XML tags like Building 
type=House or House, shouldn't be very difficult to do.

-- Max
maxnoel_fr at yahoo dot fr -- ICQ #85274019
Look at you hacker... A pathetic creature of meat and bone, panting 
and sweating as you run through my corridors... How can you challenge a 
perfect, immortal machine?

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Changing a class into a subclass

2005-03-24 Thread Bob Gailer


At 10:30 AM 3/24/2005, Max Noel wrote:
On Mar 24, 2005, at 18:07,
Ismael Garrido wrote:
Hello.
I have a program that saves/loads to/from XML. I have a main class
Building, and a subclass House(Building). When I save the code I instruct
each object to save itself to XML (using ElementTree), so House adds
itself to the XML tree.
My problem is when I load the XML. Before having subclasses what I did
was to send the XML object (again in ElementTree) to the object and let
itself load. Now, with subclasses, if I send the House XML to Building I
get a Building instance, when I need a House instance.
You can't
make an object transform into an object of a different
class
Are you referring to a Python object? If so you may assign a class to the
object's __class__ attribute.
class A:pass
class B:pass
b = b()
print b.__class__ # displays class __main__.B at 0x011BB9C0
b.__class__ = A
print b.__class__ # displays class __main__.A at
0x011BBA20
[snip]

Bob Gailer
mailto:[EMAIL PROTECTED]
510 558 3275 home
720 938 2625 cell 

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Changing a class into a subclass

2005-03-24 Thread Alan Gauld
  let itself load. Now, with subclasses, if I send the House XML to
  Building I get a Building instance, when I need a House instance.

 You can't make an object transform into an object of a different
 class. You need to identify what class the object will be an
instance
 of before loading it. Which, if you're using XML tags like Building
 type=House or House, shouldn't be very difficult to do.

Absolutely, looks like you answered your own question... :-)

But if you want an OOP approach thre are some things to try.
First you can create a BuildingFactory class that has a
single instance (or indeed no instances because you could
use a static method... or get really fancy and create a
meta-class!). The factory class then takes the XML string
fragment and figures out which subclass of Building to
create and returns the required object. You can avoid
having to recode the factory class each time by using a
dictionary object and each subclass definition adds an entry
to the Factory class dictionary - possibly by calling a
class method of Building in the __init__() code


class Shack(Building):
   def __init__(self,p1,p2...):
  Building.__init__(self,...)
  Building.register(self,'Shack', Shack)
  ...rest of init...

Now the factory code can go
 name = self.getClassName(xmlString)
 obj = self.classList[name]()

and instantiate a Shack object.

But unless you expect to create an awful lot of subclasses,
or just want to be purist in approach its probably overkill!

Alan G.

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Changing a class into a subclass

2005-03-24 Thread Alan Gauld
 Are you referring to a Python object? If so you may assign a class
to the
 object's __class__ attribute.
 class A:pass
 class B:pass
 b = b()
 print b.__class__ # displays class __main__.B at 0x011BB9C0
 b.__class__ = A
 print b.__class__ # displays class __main__.A at 0x011BBA20

Interesting Bob, but presumably that doesn't change the internal
state so the OP would need to run an initialise method using
the XML? Or no, I suppose if he did this inside the class's
init method, as the first step, it would then initialise as
usual?

I feel a spell at the  coming on...

The problem is you still need to identify the class itself
(not the class name) before you can do this, but I guess you
might get that from either the builtins dictionary or the
Building module if it has all the Building subclasses in?

But it certainly does allow you to 'convert' from one class
to another, much like the C++ cast operator.

Alan g.
Learning something new every day.

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Changing a class into a subclass

2005-03-24 Thread Kent Johnson
Alan Gauld wrote:
But if you want an OOP approach thre are some things to try.
First you can create a BuildingFactory class that has a
single instance (or indeed no instances because you could
use a static method... or get really fancy and create a
meta-class!). 
or make it a static method of Building or get really simple and use a 
module-level function...
The factory class then takes the XML string
fragment and figures out which subclass of Building to
create and returns the required object. You can avoid
having to recode the factory class each time by using a
dictionary object and each subclass definition adds an entry
to the Factory class dictionary - possibly by calling a
class method of Building in the __init__() code
class Shack(Building):
   def __init__(self,p1,p2...):
  Building.__init__(self,...)
  Building.register(self,'Shack', Shack)
  ...rest of init...
I think you want to register Shack before you ever create one. You could do 
it after Shack is defined:
class Shack(Building):
   def __init__(self,p1,p2...):
  Building.__init__(self,...)
  ...rest of init...
Building.register('Shack', Shack)
or you could probably get tricky and do it in a metaclass...but I'm not that 
tricky.
Kent
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Changing a class into a subclass

2005-03-24 Thread Ismael Garrido
Alan Gauld wrote:
Absolutely, looks like you answered your own question... :-)
But if you want an OOP approach thre are some things to try.
First you can create a BuildingFactory class that has a
single instance (or indeed no instances because you could
use a static method... or get really fancy and create a
meta-class!). The factory class then takes the XML string
fragment and figures out which subclass of Building to
create and returns the required object. You can avoid
having to recode the factory class each time by using a
dictionary object and each subclass definition adds an entry
to the Factory class dictionary - possibly by calling a
class method of Building in the __init__() code
 

My current aproach is something like that. I subclassed 
Building(Building) :-)  and wrote there the factory which returns self 
of the created instance. But that didn't go with all my other classes 
that have, as a design rule, that they manage the loading and saving 
from/to XML. That meant that Building was different to the other 
classes, and instead of doing:
a = Ship()
a.fromXML(xml)
listOfA.append(a)

I had to do:
a = Building()
listOfBuildings.append(a.fromXML(xml))
When I wrote my factory I thought about the dictionary approach, but I 
didn't write it because I hoped I could find something like the 
__class__ thing. Which, btw, is pure magic :-)

But there's something that I couldn't understand. In the following code, 
my guess would be that I'm back from the death would never get 
printed... but it is... and twice! Why?

 class A:
   def pong(self):
   print self.__class__
   print Ping!
   self.times -=1
   if self.times = 0:
   self.__class__ = B
   self.pong()
 class B:
   def pong(self):
   print self.__class__
   print Pong!
   self.times -=1
   self.__class__ = A
   self.pong()
   print I'm back from the death
  
 a = A()
 a.times = 3
 a.pong()
__main__.A
Ping!
__main__.B
Pong!
__main__.A
Ping!
__main__.B
Pong!
__main__.A
Ping!
I'm back from the death  ##Weird!
I'm back from the death
 a.__class__
class __main__.A at 0x00C1AF00

Thanks,
Ismael
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Changing a class into a subclass

2005-03-24 Thread Kent Johnson
Ismael Garrido wrote:
But there's something that I couldn't understand. In the following code, 
my guess would be that I'm back from the death would never get 
printed... but it is... and twice! Why?
It's printed every time B.pong() is called, just as Pong is. You print 
each one twice - no mystery!
Kent
  class A:
   def pong(self):
   print self.__class__
   print Ping!
   self.times -=1
   if self.times = 0:
   self.__class__ = B
   self.pong()
  class B:
   def pong(self):
   print self.__class__
   print Pong!
   self.times -=1
   self.__class__ = A
   self.pong()
   print I'm back from the death
   a = A()
  a.times = 3
  a.pong()
__main__.A
Ping!
__main__.B
Pong!
__main__.A
Ping!
__main__.B
Pong!
__main__.A
Ping!
I'm back from the death  ##Weird!
I'm back from the death
  a.__class__
class __main__.A at 0x00C1AF00
Thanks,
Ismael
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor