user3398505 user3398505 - 29 days ago 6
Python Question

Return a tuple of objects

In the

Person
object, there is already a support for an inventory, and when the
Person

object takes a
Weapon
object or
Food
object, the object would go to the inventory. For
our
Tribute
object, we want a way for us to retrieve the
Weapon
and
Food
objects from
the inventory.
Create a new method in the
Tribute
class,
get weapons()
, which would return a
tuple of
Weapon
objects that the
Tribute
currently has in his inventory

class Tribute(Person):


def get_weapon(self):
for item in self.get_inventory():
if isinstance(item, self.RangedWeapon):
return tuple(item)
else:
pass

cc = Tribute("Chee Chin", 100)
chicken = Food("chicken", 5)
aloe_vera = Medicine("aloe vera", 2, 5)
bow = RangedWeapon("bow", 4, 10)
sword = Weapon("sword", 2, 5)

Base = Place("base")
Base.add_object(cc)
Base.add_object(chicken)
Base.add_object(aloe_vera)
Base.add_object(bow)
Base.add_object(sword)

cc.take(bow) # Chee Chin took bow
cc.take(sword) # Chee Chin took sword
cc.take(chicken) # Chee Chin took chicken
cc.take(aloe_vera) # Chee Chin took aloe_vera



def add_object(self, new_object):
if isinstance(new_object, Thing) or isinstance(new_object, LivingThing):
self.objects.append(new_object)
new_object.place = self
else:
GAME_LOGGER.warning("You can only add Thing or LivingThing to {}".format(self.get_name()))

def named_col(col):
# Only accepts tuple/list
type_col = type(col)
if type_col != list and type_col != tuple:
return None

return type_col(map(lambda x: x.get_name() if isinstance(x, NamedObject) else x, col))


When I try to
print(named_col(cc.get_weapons()))
I am getting an error

AttributeError: 'RangedWeapon' object has no attribute 'owner'


class Thing(MobileObject):
def __init__(self, name):
super().__init__(name, None)
self.owner = None

def set_owner(self, owner):
self.owner = owner

def get_owner(self):
return self.owner

def is_owned(self):
return self.owner is not None


RangedWeapon is previously define under this class
class RangedWeapon(Weapon):

Answer

Here:

if isinstance(item, self.RangedWeapon):
    return tuple(item)

You aren't returning a tuple of all weapons, you're converting one weapon from a named tuple to a regular tuple and returning the single object. This strips the named attributes, hence the error. Instead, you need something like:

def get_weapon(self):
    weapons = []
    for item in self.get_inventory():
        if isinstance(item, RangedWeapon):
            weapons.append(item)
    return tuple(weapons)

You should also move all of the code outside get_weapon (cc = Tribute("Chee Chin", 100) onwards) outside the class entirely, i.e. dedent it all one more tab.

Comments