0

I have the following in a Python script:

setattr(stringRESULTS, "b", b)

Which gives me the following error:

AttributeError: 'str' object has no attribute 'b'

Can any-one telling me what the problem is here?

DSM
  • 342,061
  • 65
  • 592
  • 494
Eden Crow
  • 14,684
  • 11
  • 26
  • 24
  • The error message seems pretty clear... what's your problem? –  Feb 11 '12 at 15:14
  • I want to make dynamic variables that work like this: (string contained in variable STRINGRESULTS).b = (string contained in variable b) Which I'm told I can use with setattr: [link](http://docs.python.org/py3k/library/functions.html#setattr) But doing what I think it tells me to do in the Python doc results in that error. – Eden Crow Feb 11 '12 at 15:18
  • @EdenCrow: just to be clear, are you attempting to add an attribute called "b" to the stringRESULTS object, or are you attempting to add an attribute called b to an object *named by* the contents of stringRESULTS, so that if stringRESULTS was the string "fred", and b was 7, you'd want it to dynamically do the equivalent of "fred.b = 7"? – DSM Feb 11 '12 at 15:51
  • The second one (where fred.b = 7 in your example). – Eden Crow Feb 11 '12 at 16:15

2 Answers2

3

Don't do this. To quote the inestimable Greg Hewgill,

"If you ever find yourself using quoted names to refer to variables, there's usually a better way to do whatever you're trying to do."

[Here you're one level up and using a string variable for the name, but it's the same underlying issue.] Or as S. Lott followed up with in the same thread:

"90% of the time, you should be using a dictionary. The other 10% of the time, you need to stop what you're doing entirely."

If you're using the contents of stringRESULTS as a pointer to some object fred which you want to setattr, then these objects you want to target must already exist somewhere, and a dictionary is the natural data structure to store them. In fact, depending on your use case, you might be able to use dictionary key/value pairs instead of attributes in the first place.

IOW, my version of what (I'm guessing) you're trying to do would probably look like

d[stringRESULTS].b = b

or

d[stringRESULTS]["b"] = b

depending on whether I wanted/needed to work with an object instance or a dictionary would suffice.

(P.S. relatively few people subscribe to the python-3.x tag. You'll usually get more attention by adding the bare 'python' tag as well.)

Community
  • 1
  • 1
DSM
  • 342,061
  • 65
  • 592
  • 494
  • Re: tags - use `python-X` tag for when your problem is specific to version X of python. If it's general, use `python` as DSM suggests. – Daenyth Feb 11 '12 at 18:57
  • OK. I will have a look into using dictionaries and using the python tag in future questions - Thanks! – Eden Crow Feb 12 '12 at 15:59
0

Since str is a low-level primitive type, you can't really set any arbitrary attribute on it. You probably need either a dict or a subclass of str:

class StringResult(str):
    pass

which should behave as you expect:

my_string_result = StringResult("spam_and_eggs")
my_string_result.b = b

EDIT:

If you're trying to do what DSM suggests, ie. modify a property on a variable that has the same name as the value of the stringRESULTS variable then this should do the trick:

locals()[stringRESULTS].b = b

Please note that this is an extremely dangerous operation and can wreak all kinds of havoc on your app if you aren't careful.

aviraldg
  • 9,531
  • 6
  • 41
  • 56