Creating or assigning variables from a dictionary

2019-01-12 03:15发布

问题:

I tried to ask a question normally once in here but nobody understands what I want to ask. So I've found example in PHP.

// $_POST = array('address' => '123', 'name' => 'John Doe');
extract($_POST);
echo $address;
echo $name

is there's a function like extract() in PYTHON?????

So the same goes to dictionary:

mydict = {'raw':'data', 'code': 500}
// some magic to extract raw and code as vars
print raw 

p.s. why I want to do this: when you're in class method, it's damned hard to have 6 manipulation with strings in join() and format() when string is self.data['raw']['code'] (assume it's dict in dict in here)

回答1:

You can use the locals() function to access the local symbol table and update that table:

>>> mydict = {'raw': 'data', 'code': 500}
>>> locals().update(mydict)
>>> raw
'data'
>>> code
500

Modifying the symbol table that way is quite unusual, though, and probably not the way to go. Maybe you need to change your design so you can use the mydict dictionary instead of actual variables.



回答2:

Horribly late to the game, but I needed exactly this, and my solution was:

mydict = {'raw':'data', 'code': 500}
raw, code = [mydict.get(k) for k in ['raw','code']]

That way it's explicit for reading and there's no potential clobbering of locals() (which is a magic that I'd rather avoid).



回答3:

OK php brothers so here is a bad news, python can't create variables from out of space... like php can: ${$var} . To use local() is a very bad idea, because you'll have tons of problems with debugging, and there some locals already defined in there.. so it's really bad thing to do...

You can't create this programmatically like php does. I think it's called non-explicity, and this is one python general: You ALWAYS know variable name. This kind of stuff just a suicide in some cases, you need to write by hand tons of vars... Mostly i was unhappy because of things like XML parsing, but it appears that there are method how to convert python dictionary into class, I was told about this yesterday but still haven't checked how it works ( something like here )



回答4:

I recommend creating a class to hold the variables you're trying to create. Alex Martelli's famous bunch recipe would get you almost all of the convenience you are asking for, without resorting to modifying the local symbol table (which the docs specifically warn against doing).



回答5:

Nothing really new here, just a consolidation of one anwser and an illustration of what @John Y meant in his answer:

mydict = {'raw': 'data', 'code': 500}

def extract(dct, namespace=None):
    if not namespace: namespace = globals()
    namespace.update(dct)

extract(mydict)
print raw
print code

class Extract:
    def __init__(self, dct):
        self.__dict__.update(dct)

obj = Extract(mydict)
print obj.raw
print obj.code


回答6:

You can also use the exec keyword in a loop.

d = dict(param='hello', param2=500, param3=[1,2,3])
for k, v in d.iteritems():
    exec '%s = v' % k

But this certainly feels unpythonic. exec feels a bit esoteric and you should probably just restructure your code so you don't have to do this.



回答7:

I tried @Frédéric Hamidi's answer and found that locals() only works in the main script and does NOT work in any functions. So I did a bit of searching, and find out that locals() is READ ONLY. The reason it works in main script, is probably cause locals() is the same as globals() there, and globals() can be modified.

So I would suggest using globals().update() instead.

But it is going to pollute your global namespace. So this trick is even less clean than locals().