0

A python beginner here. Sorry if this question is dumb. I am simply trying to access an instance classes' method ( addComponentToIC ) via a "variablized" object/instance name read in from a dictionary.

I create a dictionary looks like this:

qaDict = {} # a place to store the DSIDs/names for later use

jd = r.findDSIDs('My QA Team', 'External') # make the call to get unique IDs

for a in jd:

(a['lastName']).lower() + '_' + (a['firstName']).lower() #name the object   using "last_name_firstName"
if a['dsid'] not in blacklistedDSIDs:
    globals()[qaperson] = Ic(a['dsid'], a['lastName'], a['firstName']) ## create the Ic object
    qaDict[a['dsid']] = qaperson  ## add person to list of DSIDs

Then I want to take those IDs and grab all the components they are verifier on:

for key, value in qaDict.items():

    jd = r.findComponents(key)  
    getattr(value, 'addComponentToIC')(jd['id'], jd['name'])

I get a : AttributeError: 'unicode' object has no attribute 'addComponentToIC'

I have also tried:

for key, value in qaDict.items():

    jd = r.findComponents(key)  
    value.addComponentToIC(jd['id'], jd['name'])

That also throws the same error. So it seems like it's something to do with the variable name "value", not actually being interpreted as the instance name. It is supposed to wind up looking like:

employees_name.addComponentToIC(jd['id'], jd['name']) 

-- where "employees_name" is an instance of the class previously created, but it doesn't work. I know there is something silly I am not understanding here ;-) Any help would be greatly appreciated!

My Class looks like this:

class Ic(object):

    'This is a class for QA folks'

    empCount = 0

    @classmethod
    def displayEmployeeCount(class_obj):
        print ("The total employee count is %d" % Ic.empCount)

    def __string__(self):
        return str(self)

    def __init__(self, dsid, fname, lname):

        self.dsid = dsid
        self.fname = fname
        self.lname = lname
        self.name = fname + ' ' + lname
        Ic.empCount += 1
        self.ticketCount = 0
        self.componentCount = 0
        self.componentDict = {}
        self.componentName = ''
        #Ic.instances.add(self)

    def addComponentToIC(self, componentID, componentName):
        self.componentName = componentName
        self.componentID = componentID
        self.componentDict[componentID] = componentName

    @classmethod
    def get_instances(cls):
        return list(Ic.instances)

    def addTicketCount(self, count):
        self.ticketCount += count

    def addComponentCount(self, count):
        self.componentCount += count

    def displayComponentNumber(self):
        print (self.name, " has ", len(self.componentDict), " number of components.")

    def displayEmployee(self):
        print ("Name: ", self.name, "DSID: ", self.dsid, "Count: ", self.ticketCount, ", Component Count: ", len(self.componentDict))

    def displayComponentDict(self):
        print ("This employee is verifier for the following components: ", self.componentDict)
Brian
  • 1
  • 2
  • please complete your question title – lanyusea Apr 06 '15 at 03:58
  • I am trying to figure out how to ;-) – Brian Apr 06 '15 at 04:00
  • @Brian What does the dictionary contain? What sorts of objects are in the values? –  Apr 06 '15 at 04:04
  • Tell us how your var qaDict is assembled? – flycee Apr 06 '15 at 04:05
  • Also what is r, and what is its findComponents method? –  Apr 06 '15 at 04:06
  • Hi -- it looks like this: "524568638 jones_henry" when I print key, value. Is that enough info? jones_henry is the name I am trying to use as a call to the instance named "jones_henry". – Brian Apr 06 '15 at 04:07
  • @NotNotLogical thanks for the help! The r is just a handler that calls our backend database and grabs the list of components based on a unique id for the QA person. Does that make sense? – Brian Apr 06 '15 at 04:10
  • @Brian But what is the type of value? Use print(type(value)) to get that programmatically. It looks like it is just a string, or perhaps something else, which does not have that field you are trying to call. –  Apr 06 '15 at 04:12
  • I can't understand your question, you can see the type of this value using print type(value) ... if this is Ic instance, you can type print dir(value) to show the variables that you have access – geoom Apr 06 '15 at 04:13
  • Thanks guys--it says: when I add "print type(value)" to the loop – Brian Apr 06 '15 at 04:17
  • So it's not an Ic instance at all. It's just plain text (I'm guessing that's what 'unicode' means, unless that is a class you designed). Plain text doesn't have that attribute. –  Apr 06 '15 at 04:19
  • @flycee I added to the code section above how qaDict is assembled – Brian Apr 06 '15 at 04:20
  • Looks like `qaperson` is a unicode string that is used to index into globals() and then assigned as the value in your dictionary. The value of `qaperson` is now available in the global space, e.g. qaperson = "fred", `fred` is now an instance of Ic. – AChampion Apr 06 '15 at 04:29

2 Answers2

0

qaperson will always point to the unicode object. To access the value of the global name that is pointed to qaperson, you have to access it through globals(). Here is an example of what is happening.

>>> class Foo(object):
    def __init__(self, n):
        self.n = n
    def bar(self):
        print self.n, 'bar!'

>>> x = 'k'
>>> globals()[x] = Foo(x)
>>> x
'k'
>>> x.bar()

Traceback (most recent call last):
  File "<pyshell#38>", line 1, in <module>
    x.bar()
AttributeError: 'str' object has no attribute 'bar'
>>> k
<__main__.Foo object at 0x03FD02F0>
>>> k.bar()
k bar!
>>> globals()[x]
<__main__.Foo object at 0x03FD02F0>
>>> globals()[x].bar()
k bar!
>>> 
>>> d = {1:x}
>>> d
{1: 'k'}
>>> d[1].bar()

Traceback (most recent call last):
  File "<pyshell#45>", line 1, in <module>
    d[1].bar()
AttributeError: 'str' object has no attribute 'bar'
>>> globals()[d[1]]
<__main__.Foo object at 0x03FD02F0>
>>> globals()[d[1]].bar()
k bar!
>>>

Maybe you should just use the IC instance for the qaDict values:

if a['dsid'] not in blacklistedDSIDs:
    ic = Ic(a['dsid'], a['lastName'], a['firstName']) ## create the Ic object
    globals()[qaperson] = ic
    qaDict[a['dsid']] = ic  ## add person to list of DSIDs
    # or
    #qaDict[ic.dsid] = ic

Then using my example, you would use it like this

>>> x = 'k'
>>> f = Foo(x)
>>> d = dict()
>>> d[f.n] = f
>>> d
{'k': <__main__.Foo object at 0x03FC2A70>}
>>> for k,v in d.items():
    print k
    v.bar()

k
k bar!
>>> 
wwii
  • 23,232
  • 7
  • 37
  • 77
  • Thanks a ton for the help @wwii ! I now have an object like this: 524568638 , but I am still unable to call the method on it within this loop: for key, value in qaDict.items(): print key, value jd = r.findComponents(key) # make the call to get DSIDs print type(value) try: self.addComponentToIC(jd['id'], jd['name']) except: traceback.print_exc() I get : TypeError: list indices must be integers, not str – Brian Apr 06 '15 at 05:28
  • Maybe something like this is what I should be doing to store, and later modify an instance? http://stackoverflow.com/questions/4831307/is-it-bad-to-store-all-instances-of-a-class-in-a-class-field – Brian Apr 06 '15 at 05:55
  • @Brian, Yep you could do that but if you just add the instances to ```qaDict``` you will be able to retrieve and operate them later - see edit. – wwii Apr 07 '15 at 03:47
0

I got this sorted out--thanks to all for your help. I tried to figure out how to "choose" the answer from WWii, but it won't let me upvote it. This site is kind of hard to figure out for me too--not just python.

Anyway, here is what I eventually got working:

objs = []
for a in jd:

    fullname = (a['lastName']).lower() + '_' + (a['firstName']).lower() #name the object using "last_name_firstName"

    if a['dsid'] not in blacklistedDSIDs:

        x = Ic(fullname, a['dsid'])
        objs.append(x)

for employee in objs:
    employee.addTicketCount(5)

for employee in objs:
    employee.displayEmployee()
Brian
  • 1
  • 2