Why would you want to do such a thing? Unless you actually do anything with the variables inside the function, a function that just assigns several variables and then discards them is indistinguishable to def foo(): pass (An optimiser would be justified in generating exactly the same bytecode).
If you also want to dynamically append code that uses the values, then you could do this by using exec (though unless this is really user-input code, there are almost certainly better ways to do what you want). eg:
some_code = ' return a+b+c'
exec "def foo():\n " + '\n '.join('%s = %s' for k,v in bar.items()) + '\n' + some_code
(Note that your code must be indented to the same level.)
On the other hand, if you want to actually assign these values to the function object (so you can do foo.a and get 1 - note that your sample code doesn't do this), you can do this by:
for key, val in bar.items():
setattr(foo, key, val)