443,907 Members | 2,031 Online
Need help? Post your question and get tips & solutions from a community of 443,907 IT Pros & Developers. It's quick & easy.

# Subclasses in Python

 P: n/a I'm teaching myself programming using Python, and have a question about subclasses. My game has two classes, Player and Alien, with identical functions, and I want to make Player a base class and Alien a derived class. The two classes are described below class Player(object): #Class attributes for class Player threshold = 50 n=0 #n is the number of players #Private methods for class Player def __init__(self,name): self.name = name self.strength = 100 Player.n +=1 def __del__(self): Player.n -=1 print "You got me, Alien" #Public methods for class Player def blast(self,enemy,energy): enemy.hit(energy) def hit(self,energy): self.strength -= energy if(self.strength <= Player.threshold): self.__del__() class Alien(Player): #Class attributes for class Alien threshold = 100 n=0 #n is the number of players #Private methods for class Alien def __init__(self,name): self.name = name self.strength = 100 Alien.n +=1 def __del__(self): Alien.n -=1 print "You got me, earthling" #Public methods for class Alien def hit(self,energy): self.strength -= energy if(self.strength <= Alien.threshold): self.__del__() The two classes are almost identical, except that: 1. When a new player is instantiated or destroyed, Player.n is incremented/decremented, while when a new alien is instantiated, Alien.n is incremented/decremented. 2. When hit by an energy blast, the player and the alien have different thresholds below which they die. How can I base the Alien's __init__(), __del__() and hit() methods on the Player's methods, while ensuring that the appropriate class variables are incremented/decremented when a new object is instantiated and that the appropriate threshold is used when the player/alien is hit by an energy bolt? Thomas Philips Jul 18 '05 #1
5 Replies

 P: n/a tk****@hotmail.com (Thomas Philips) wrote: I'm teaching myself programming using Python I'm not sure how to parse that. Do you mean, "I'm teaching myself programming, and I'm using Python", or do you mean, "I already know how to program, and now I'm teaching myself Python"? and have a question about subclasses. My game has two classes, Player and Alien, with identical functions, and I want to make Player a base class and Alien a derived class. [...] The two classes are almost identical, except that: 1. When a new player is instantiated or destroyed, Player.n is incremented/decremented, while when a new alien is instantiated, Alien.n is incremented/decremented. It sounds from your description that you really want Player and Alien to both be subclasses of a common base class. The reason I say that is because Player.n doesn't get incremented when you create an Alien. 2. When hit by an energy blast, the player and the alien have different thresholds below which they die. Again, this sounds like two subclasses of a common base class; let's call it Humanoid. It sounds like hit() and blast() belong in Humanoid, and the "n" attribute should be a class variable of Alien and Player, each of which have their own __init__(). It's not clear what to do with "self.strength = 100" which currently you've got in each Player.__init__() and Alien.__init__(). One possibility is that you could factor this out into Humanoid.__init__(), and have each of the subclass's __init__() call Humanoid.__init__ (self). The other possibility is to just leave it in each subclass's __init__() and not have a base class __init__() at all. The XP folks would yell "refactor mercilessly", but in this case I'm not sure it's justified. BTW, there's nothing in the above that's specific to Python. The same arguments would work in pretty much any OOPL. Jul 18 '05 #2

 P: n/a Thomas Philips wrote: I'm teaching myself programming using Python, and have a question about subclasses. My game has two classes, Player and Alien, with identical functions, and I want to make Player a base class and Alien a derived class. The two classes are described below The two classes are almost identical, except that: 1. When a new player is instantiated or destroyed, Player.n is incremented/decremented, while when a new alien is instantiated, Alien.n is incremented/decremented. 2. When hit by an energy blast, the player and the alien have different thresholds below which they die. How can I base the Alien's __init__(), __del__() and hit() methods on the Player's methods, while ensuring that the appropriate class variables are incremented/decremented when a new object is instantiated and that the appropriate threshold is used when the player/alien is hit by an energy bolt? Thomas Philips One easy solution is to use self.__class__.n and self.__class__.threshold instead of explicit Player.n and Player.threshold. Then derive Alien from Player and only keep the two class attributes in it. Get rid of all methods in Alien. If you haven't already guessed how this works: when you call any method on an Alient object, self.__class__ will be Alien, and if you call a method on a Player object, self.__class__ will be Player. -- Shalabh Jul 18 '05 #3

 P: n/a I followed Shalabh's suggestion and rewrote Alien as a subclass of Player, and used self.__Class__. to access the class attributes in the class and subclass. Works like a charm, but I'm having some difficulty printing class names. I want self.__class__ to return just the name of the class without some ancillary stuff thrown in. A snippet of code follows: class Player(object): #Class attributes for class Player threshold = 50 initial_strength=100 n=0 #Private methods for class Player def __init__(self,name): self.name = name self.strength = self.__class__.initial_strength self.__class__.n +=1 print self.__class__ class Alien(Player): #Class attributes for subclass Alien threshold = 30 initial_strength=150 n=0 When a new object is instantiated, the print statement in __init__ gives me or How can I just get it to return Player or Alien Interestingly, if I do a class comparison of the form if self.__class__== Alien: foo elif self.__class__== Player bar The comparison proceeds correctly. How can I get it to print the class name cleanly? Do I have to convert to a string and then use one or more string functions to clean it up? Thomas Philips Jul 18 '05 #4

 P: n/a Thomas Philips wrote: I followed Shalabh's suggestion and rewrote Alien as a subclass of Player, and used self.__Class__. to access the class attributes in the class and subclass. Works like a charm, but I'm having some difficulty printing class names. I want self.__class__ to return just the name of the class without some ancillary stuff thrown in. A snippet of code follows: class Player(object): #Class attributes for class Player threshold = 50 initial_strength=100 n=0 #Private methods for class Player def __init__(self,name): self.name = name self.strength = self.__class__.initial_strength self.__class__.n +=1 print self.__class__ make that print self.__class__.__name__ class Alien(Player): #Class attributes for subclass Alien threshold = 30 initial_strength=150 n=0 When a new object is instantiated, the print statement in __init__ gives me or How can I just get it to return Player or Alien Interestingly, if I do a class comparison of the form if self.__class__== Alien: This compares two *classes* not classnames. Even classes with the same name defined, say, in a function would be recognized as not equal: def makeClass(): .... class A(object): pass .... return A .... A1 = makeClass() A2 = makeClass() A1 A2 A1 == A2 False Now compare the names: A1.__name__, A2.__name__ ('A', 'A') A1.__name__ == A2.__name__ True foo elif self.__class__== Player bar The comparison proceeds correctly. How can I get it to print the class name cleanly? Do I have to convert to a string and then use one or more string functions to clean it up? No, "" is the string that is generated when the class Alien is converted to string. If you want something else you have to change to a custom metaclass - better stick to Alien.__name__. Peter Jul 18 '05 #5

 P: n/a You have needed edit already. To explain a bit more ... #Private methods for class Player def __init__(self,name): self.name = name self.strength = self.__class__.initial_strength self.__class__.n +=1 print self.__class__ print object # is same as print str(object) # ie, prints stringifies everything Interestingly, if I do a class comparison of the form if self.__class__== Alien: foo elif self.__class__== Player bar The comparison proceeds correctly. Here self.__class__ is left as the class object, as usual, and not stringified. How can I get it to print the class name cleanly? Do I have to convert to a string That is what you did to print it '-) and then use one or more string functions to clean it up? Fortunately not. Terry J. Reedy Jul 18 '05 #6

### This discussion thread is closed

Replies have been disabled for this discussion.