Caleb Larson
Caleb Larson

Reputation: 3

Python - Using a list of objects, Attribute Error

I have an orc object, and a radar object that needs to keep track of orcs it can see. I'm keeping track of orcs using a list, but when I try to pull an orc (or data about it) out of the list I get an attribute error.

The exact error is:

AttributeError: type object 'orc' has no attribute 'name'

Here's the radar class

from source.orc import orc

class radar(object):
    """
    radar Class
    """
    def __init__(self, maxOrcs=25):
        self.maxOrcs = maxOrcs
        self.numOrcs = 0
        self.orcList = [orc]
        logger.info('Radar created!')

    def addOrc(self, orc=None):
        self.numOrcs = self.numOrcs +1
        self.orcList.append(orc)
        logger.info('Orc added to battlefield!')

    def distance(self, name):
        retVal = None
        logger.debug('calculating distance')
        for orc in self.orcList:
            if name in orc.name:
                retVal = ( (500 - orc.locx) + (500 - orc.locy) )
                break
        return retVal

If it helps at all here's the orc class

class orc(object):  #Orc class
    def __init__(self, name='Krusk', locx=1, locy=1, speed=1):
        #set name
        if(len(name) < 20):
            self.name = name
        else:
            self.name = 'Krusk'
            logger.warning('Default name used')


        #set x coord
        if(isinstance(locx, int) != True):
            self.locx = 1
            logger.warning('x coordinate set to 1, Not an int')
        elif(locx < 1):
            self.locx = 1
            logger.warning('x coordinate set to 1, passed value to low')
        elif(locx > 1000):
            self.locx = 1000
            logger.warning('x coordinate set to 1000, passed value to high')
        else:
            self.locx = locx


        #set y coord
        if(isinstance(locy, int) != True):
            self.locy = 1
            logger.warning('x coordinate set to 1, Not an int')
        elif(locy < 1):
            self.locy = 1
            logger.warning('y coordinate set to 1, passed value to low')
        elif(locy > 1000):
            self.locy = 1000
            logger.warning('x coordinate set to 1000, passed value to high')
        else:
            self.locy = locy


        #set speed
        if(speed < 0):
            self.speed = 0
            logger.warning('speed set to 0, passed value cannot be negative')
        else:
            self.speed = speed

        logger.info('Orc created!')

Upvotes: 0

Views: 113

Answers (2)

Alan Hoover
Alan Hoover

Reputation: 1440

I agree with others that this line of code is the problem:

        self.orcList = [orc]

I, however, disagree with them on what to do about it. I think you don't want to put anything in your list at that point in your initializer. I think you want to create an empty list:

        self.orcList = []

that will be ready to accept entries when you add them calling addOrc(). This aligns with setting the count to 0 in your initializer. And makes the most sense, since your initializer does not receive an orc object to add to the list.

Edit:

Since you are retrieving from the list by name, you might consider using a dict keyed by name for your storage rather than a list. A dict would allow you to directly access the desired orc, instead of having to go through the entire list until you find the one you want.

self.orclist = {}

self.orclist[orc.name] = orc

chosen = self.orclist[name]
# do whatever with chosen

instead of:

for orc in self.orclist:
    if orc.name == name:
       # do whatever

Upvotes: 2

Martijn Pieters
Martijn Pieters

Reputation: 1121406

You did not create an instance of your orc class here:

self.orcList = [orc]

You used the class there, and the orc class has no name attribute. Perhaps you meant to create an instance instead:

self.orcList = [orc()]

Your code is also using orc both as the name of class and as local variables (in loops or as function arguments), increasing the potential for confusion here.

You should use CamelCase naming for your classes to avoid this; see the Python styleguide:

class Orc(object):

and

class Radar(object):

and creating your instance becomes:

self.orcList = [Orc()]

although self.orc_list would be better, if you are following the styleguide anyway.

Upvotes: 4

Related Questions