2

I have a Python dictionary that labels key name to attributes. The program that is tied to this dictionary is set to only have a few of the items, and only if they are necessary. So not all attributes in dictionary are defined at every pass of this script.

Here is the code with the dictionary

def getWidths(self,sheetName):
    sheets = {
        'dclabels':self.dclabels,
        'tdclabels':self.tdclabels
    }

    sheetName = sheetName.lower()
    if sheetName in sheets: 
        return sheets.get(sheetName) 
    else:
        return self.colWidths

I am getting an error stating AttributError: ClassName instance has no attribute 'dclabels' How can I avoid this error? Is there a way I can get the script to ignore any attributes that are not defined? Thanks!

I found a the solution to my issue.

   def getWidths(self,sheetName):
       if hasattr(self, sheetName.lower()):
           name = getattr(self,sheetName.lower())
           self.name = name
           return self.name
       else:
           return self.colWidths

I made use of the hasattr() and getattr() to solve my problem. Thanks to all for your suggestions.

amlane86
  • 668
  • 4
  • 15
  • 24
  • You can substitute the last paragraph by `return sheets.get(sheetName.lower(), self.colWidths)`. – hochl Mar 14 '12 at 12:50
  • see also: http://stackoverflow.com/questions/610883/how-to-know-if-an-object-has-an-attribute-in-python – Kyss Tao Mar 14 '12 at 13:02
  • @Marcin, Sorry your solution didn't work in my case. It worked for one scenario, but not for all. Thank you for your support anyway. – amlane86 Mar 15 '12 at 18:30
  • @amlane86 In what sense does it not work? I note that you have left no comments on this topic. – Marcin Mar 15 '12 at 18:31
  • @Marcin, I posted the code I used above. You can look at it if you'd like, but plain and simple... I tried a few different suggestions and what I have above worked best for me. I realized that having a dictionary was not the right approach and that it is better to just check whether an attributes exists instead of iterating through a dictionary of possibly countless attributes to find one. The `getattr()` does that for me without me defining a dictionary of hardcoded items. – amlane86 Mar 15 '12 at 18:53

3 Answers3

5

Yes, you can query your object, and build the dict up iteratively:

for prop in ('dclabels', 'tdclabels'):
    try:
        sheets[prop] = getattr(self, prop)
    except AttributeError: pass # expected

(Style note: the PEP8 style is never to put code on a line following a colon; I find it more readable to put a suite of a single statement on the same line as the colon, as long as all the code, and any associated comment are short.)

Marcin
  • 48,559
  • 18
  • 128
  • 201
  • 1
    `prop` is undefined. I guess you mean `attr`? – Constantinius Mar 14 '12 at 13:13
  • @Constantinius Thanks, that error was introduced by another user editing my answer. – Marcin Mar 14 '12 at 13:15
  • @Mike Graham Why did you choose to introduce an error into my code? It was in no way necessary to edit the iteration variable. – Marcin Mar 14 '12 at 13:29
  • 2
    @Marcin, my mistake aside, it is evident that many people end up confused about the meaning of the term "property" in Python, so I thought it might be more helpful for you to use a more applicable term like "attribute" to promote greater clarity in technical communication. – Mike Graham Mar 14 '12 at 15:33
4

You can do it like this:

sheets = { }
attr = getattr(self, "dclabels", None)
if attr is not None:
    sheets["dclabels"] = attr

or like this:

try:
    sheets["dclabels"] = self.dclabels
except AttributeError:
    pass
Constantinius
  • 34,183
  • 8
  • 77
  • 85
  • Note that `hasattr` is broken in that it will silence any exception, not just the appropriate one. (If you hit ^C at the wrong moment, it will be swallowed up, for example.) If one insists on doing something like that, they should use something more like `if getattr(self, "dclabels", None) is None:` (or some other unique value if `None` is a valid value here.) – Mike Graham Mar 14 '12 at 15:35
0

You must to declare variables before use it like this:

class ClassName(object):
    __init__(self,dclabels=None, tdlabels=None):
         self.dclabels = dclabels
         self.tdlabels = tdlabels
Denis
  • 7,127
  • 8
  • 37
  • 58