Python Forum

Full Version: from global space to local space
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
in a function i am doing a return of the locals() dictionary. one of the values i want to include in that dictionary is in the global space (let's call it "foo"). so i was, at first, tempted to just code foo = foo which i presume would not work. what would be the appropriate way put a variable in that function's local name space, taking its value from the same name in the global name space.

i figure what i should do is:
d = locals()
d['foo'] = foo
return d
but this has got me curious if there is a direct one expression way to do that (in or before a return statement).
I don't think there's a way to shortcut this. The local variables in a function are created when the function is defined, not when it is run. And, I don't know any method to work around the shadow of a local variable to explicitly ask for the global. If that could happen, you could set up the variable as local, but at runtime pull out the value of the global.

Without that, your trick of creating a new dictionary and adding in the (unshadowed) global seems pretty good, but of course your d will be one of the entries. That seems a little bit annoying.

With python3.9, you'll be able to do direct directory merges and return that. Until then you could get close with something like:

foo = "globalfoo"
def myfunc():
    locala = 12
    localb = "hello"
    return {**locals(), 'foo': foo}

print(myfunc())
Output:
{'locala': 12, 'localb': 'hello', 'foo': 'globalfoo'}
is d really going to be in the local space before the assignment? if so, then i would add del d['d'] in there.
You're correct. locals() will only show them after assignment. I had done some testing that made me think otherwise, but that was just an error on my side.
i think locals() is returning a reference to the local name space rather than a copy of it. so another option is d = dict(locals()). now will d contain itself. i'll have to try that after posting this thought.

yay, d is not in there.
#!/usr/bin/env python3

gamma = ['me','too']

def f():
    alpha = 6
    beta = 'foo'
    d = dict(locals())
    d['gamma'] = gamma
    return d

x = f()
print(repr(x))

i think i need to try out this little idea:
def dictdeladd(*args,**kwargs):
    """Copy a dictionary (arg 1), deleting items (args 2 ..) and adding items (key word args)."""
    if args:
        d = args[0]
        if not d:
            d = {}
        if not isinstance(d,dict):
            raise TypeError('argument 1 is not a dictionary')
        if d:
            d = dict(d)
    else:
        d = {}
    for k in args[1:]:
        if k in d:
            del d[k]
    for k,v in kwargs.items():
        d[k] = v
    return d