I'm having some trouble with classes at the minute, and I not sure of how to solve my problem. I've read the docs and I can't connect anything said there with the problem I'm having.
I'm trying to make some simple classes for a game. I have a Weapon class and a Person class. I'm trying to pass a Weapon to the Person class (I hope this makes sense), so that the Person (Bob) can use the weapon. I'm having trouble accessing the methods and attributes in the Weapon class. I've considered making Person a child class of Weapon so that it can call the method easily, but that doesn't seem intuitive to me . . .
class Weapon:
def __init__(self, weapon_name, weapon_damage):
self.weapon_name = weapon_name
self.weapon_damage = weapon_damage
def display_weapon_name(self):
print('Weapon Name: %s' %self.weapon_name)
class Person:
def __init__(self, person_name, health, ranged_weapon):
self.person_name = person_name
self.health = health
Weapon.ranged_weapon = ranged_weapon
def display_person_info(self):
print('Name: %s' %self.person_name)
print('Ranged Weapon :%s' %Weapon.display_weapon_name)
def ranged_attack(self, ranged_weapon, target):
target.health -=ranged_weapon.weapon_damage
print("Weapon: %s" %ranged_weapon.weapon_name)
print(target.person_name + "'s Health: "+str(target.health))
pistol = Weapon("Pistol", 40)
bob = Person("Bob", 100, pistol)
bob.display_person_info()
Running this gives me:
Name: Bob
Ranged Weapon :<function Weapon.display_weapon_name at 0x02E23030>
Running:
bob.ranged_attack(pistol, bob)
Gives:
Weapon: Pistol
Bob's Health: 60
My questions are, am I passing the Weapon object correctly to the Person class? It seems weird writing Weapon.ranged_weapon in _init__ rather than self.ranged_weapon.
How can I get the display_weapon_info to show the string 'Weapon Name: Pistol', rather than the reference? It seems to work when I call it in ranged_attack, but not in the display info.
Really appreciate any help I can get with this. Apologies if a similar question has been asked before, but I couldn't find anything I could relate to my issue.
Rich
If you want to extend another class in Python, taking all of its functionality and adding more functionality to it, you can put some parentheses after your class name and then write the name of the class that you're inheriting from.
yes of coarse you can pass classes or functions or even modules ...
As Java Class , we can have classes as part of another class. i.e. we can have a user defined type inside another user defined type. e.g., room having fan and lights, car having engine and tyres. This way of including classes inside other classes is also referred as class composition or has a relation. .
Person
doesn't actually need to reference the Weapon
class directly; it just needs to save a reference to whatever is passed as the ranged_weapon
argument and know what it can do with that object. The code implicitly assumes that ranged_weapon
is an instance of Weapon
, but will work with any object that is suitably similar to an instant of Weapon
.
class Person:
def __init__(self, person_name, health, ranged_weapon):
self.person_name = person_name
self.health = health
self.weapon = ranged_weapon
def display_person_info(self):
print('Name: %s' %self.person_name)
# display_weapon_name already calls print; but
# you probably don't need this method at all.
self.weapon.display_weapon_name()
# Instead, do this (actually, you already do this
# in ranged_attack())
# print('Weapon: %s' % self.weapon.weapon_name)
def ranged_attack(self, ranged_weapon, target):
target.health -= self.weapon.weapon_damage
print("Weapon: %s" % self.weapon.weapon_name)
print(target.person_name + "'s Health: "+str(target.health))
def display_person_info(self):
print('Name: %s' %self.person_name)
print('Ranged Weapon :%s' %Weapon.display_weapon_name)
Looking at this function, the compiler sees the following:
Line 1: A function named display_person_info
with the parameter self
.
Line 2: Print "Name: " and then print the name of self
Line 3: Print "Ranged Weapon: " and then Weapon.display_weapon_name
.
In line 3, the compiler, rather than printing the weapon name, it is printing the function display_weapon_name
itself! What you need to do instead is replace Line 3 with this:
print('Ranged Weapon :%s' %self.weapon.display_weapon_name())
That way, the value returned by the function is printed, rather than the function's pointer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With