2

I'm looking for a way to access variables from strings.

Like this:

A1 = {}
B1 = {}
C1 = {}

mylist = ["A","B","C"]

for blurb in mylist:
    blurb1.foo()

Right now I'm using if/elif constructions in such cases:

if blurb == "A":
    A1.foo()
elif blurb == "B":
    B1.foo()
elif blurb == "C":
    C1.foo()

That works, but surely there's a more elegant way of doing it?

I would like to create and access objects from strings.

So if I have a function that returns a string, I want to create e.g. a list using this string as the list name, and then do stuff with that list.

x = foo() # foo returns a string, e.g. "A"
# create list named whatever the value of x is
# in this case: 
A = []

Isn't there anything more elegant than preparing lists for all possible outcomes of x and using long elif constructions or dictionaries? Do I have to use eval() in that case? (I'm hesitant to use eval(), as it's considered dangerous.)

3
  • no he is looking for a way to run functions/or access variables (like his dicts above) via string conversion (or other types of conversion) Commented Aug 8, 2012 at 13:04
  • something like that, yes. How would i do that? Commented Aug 9, 2012 at 13:00
  • I've updated my answer to try to answer your revised request, but could you provide a use case why you want to do this. Commented Aug 11, 2012 at 1:52

4 Answers 4

11

I think you want something like

lookup = {"A": A1, "B": B1, "C": C1}
obj = lookup.get(blurb,None)
if obj:
   obj.foo()

This is usually suggested when someone wants to do something with a switch statement (from c/java/etc.) Note that the lookup.get (instead of just lookup[blurb] handles the case where blurb is something other than one of the values you defined it for... you could also wrap that in a try/except block.


Updated answer based on your revised question, which builds on what Joachim Pileborg had said in another answer.

There are probably better/cleaner ways to do this, but if you really want to set/get via strings to manipulate global objects, you can do that. One way would be: To create a new object named "myvariable" (or to set "myvariable" to a new value)

joe = "myvariable"
globals().update([[joe,"myvalue"]])

To get the object "myvariable" is assigned to:

globals().get(joe,None) 

(or as mentioned in another answer, you could use try/except with direct hash instead of using get)

So for later example, you could do something like:

for myobject in mylist:
    # add myobject to list called locus
    # e.g. if locus == "A", add to list "A", if locus == "B" add to list B etc.
    obj = globals().get(myobject.locus,None) # get this list object
    if not obj: # if it doesn't exist, create an empty list named myobject.locus
        obj = []
        globals().update([[myobject.locus,obj]]
    obj.append(myobject) #append my object to list called locus
Sign up to request clarification or add additional context in comments.

4 Comments

this is messy, adds a lot of extra checks and a whole extra dictionary.... not very effective for lots of data, or different types of required functions... better use eval().
eval is evil! (most of the time)
"A whole extra dictionary." Oh no, one whole dictionary! LOL!
@Foon: This works, thanks, though it was not exactly what I was looking for. Is there no way to create variable names from strings, like from the output of a function?
7

You could get the module object, and use getattr to get variables/functions from a string:

import sys

A = {}
B = {}
C = {}

modname = globals()['__name__']
modobj  = sys.modules[modname]

mylist = ["A","B","C"]

for name in mylist:
    print '%s : %r' % (name, getattr(modobj, name))

The above program will print:

A : {}
B : {}
C : {}

However, it has nothing to do with "wildcards" that you reference in your question, but you don't show any searching for "wildcards".

1 Comment

I wasn't sure how to call it. I guess "access variable from string" would have been better?
2

use eval().

example:

A1 = []
B1 = []
C1 = []

mylist = ["A","B","C"]

for blurb in mylist:
    eval("%s1.append(blurb)" % blurb)

print A1,B1,C1
>>> 
['A'] ['B'] ['C']

and for your code it can be:

for blurb in mylist:
    eval("%s1.foo()" % blurb)

2 Comments

Please definitely do not do this.
@Iguananaut Yeah, i should probably have added some disclaimer that this is a horrible solution. Feel free to edit my answer and add some warnings.
1

I looks like you simply want a dictionary and to look it up rather than run a bunch of checks.

dict_look_up = {'A' : A1, 'B' : B1, 'C' : C1}
try:
    dict_look_up[blurb].foo()
except KeyError:
    #whatever on item not found

try/except blocks are incredibly important in Python (better to ask for forgiveness than permission), so if you're learning I recommend using them from the get go.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.