tags:

views:

76

answers:

4

Hello,

Say I have a simple function:

def myfunc():
    a = 4.2
    b = 5.5
    ... many similar variables ...

I use this function one time only and I am wondering what is the easiest way to make all the variables inside the function accessible to my main name-space.

Do I have to declare global for each item? or any other suggested methods?

Thanks.

+1  A: 

I can't think of any good reason for doing this, but if you REALLY want to for some strange reason:

def myfunc():
    x = 5.6
    y = 7.3
    # many other variables
    globals().update( locals() )

This works because the globals function returns a dictionary of the global variables in your module's namespace, which you can dynamically update with the dictionary of all local variables returned by the locals function.

This is very dangerous because it will clobber everything in your global namespace, so if you already had an x or y variable, then they'll get overwritten. And as I said, I really can't think of a good reason to ever do this, so definitely think twice before resorting to this kind of trickery!

Eli Courtwright
Oh come on... I JUST ATE...
Ignacio Vazquez-Abrams
Those variables inside the function are my constants. I am collecting wide-spread common one-time declared variables in one function. I thought there should be an easy to make variables accessible to the main. Your method works fine. I will be careful about the caution. The names for the constants should be unique so I don't think I could overwrite any name, yet. Will see how the conversiton goes.
Gökhan Sever
If they're only set one time then why do they need to be in a function?
Ignacio Vazquez-Abrams
It is like collecting your apples and tangerines in a container called fruit basket. Simplifies my life. I call the function set_constants, so it is clearer.
Gökhan Sever
Then use another module for that. That's what they're for.
Ignacio Vazquez-Abrams
A: 

It sounds like what you want to do isn't natural because it isn't something you should generally do much.

Perhaps what you really want is to make a class and set all these things on an instance of it.

class MyState(object):
    def __init__(self):
        self.a = 4.2
        self.b = 5.5
        ... many similar variables ...

Storing state on an instance of a class you create is usually very strongly preferred to mutating global state. This method also does not require any magic.

Mike Graham
I am a lazy coder. I know classes work great for my use case, but it requires a lot my more key-stroke. Instantiating the class and accessing by class_instance.var. I will take the other approach for the time being until I got bitten somewhere else in the code.
Gökhan Sever
Number of characters in a source code file is a very silly thing to optimize for. Doubly so in Python, which aims to be somewhat verbose. **Being lazy is good**, but if you want to save yourself time and effort you should be making code that is maintainable, light on magic, readable, consistent, and idiomatic.
Mike Graham
+5  A: 

Best way, in my biased opinion, is to wrap the dictionary into a nice object where the "variables" are accessed as attributes -- the pattern I named Bunch when I introduced it many years ago, and a great example of the last item in the Zen of Python (if you don't know what that is, import this at an interpreter interactive prompt). To wit...:

class Bunch(object):
    def __init__(self, d=None):
        if d is not None: self.__dict__.update(d)

def myfunc():
    a = 4.2
    b = 5.5
    ...
    return Bunch(locals())

x = myfunc()

print x.a, x.b

Using qualified names like x.a and x.b, rather than barenames such as a and b, is the crucial idea here: qualified names let you separate namespaces and treat them right, while barenames would make one big soup of everything and violate the Zen of Python;-). And of course there's no need to use an unwrapped dict and unsightly x['a'], x['b'] accesses!-)

Alex Martelli
Thanks Alex for the input. Your method is even longer than Mike's. What I am looking actually an IDL equivalent of "common" in Python. See http://idlastro.gsfc.nasa.gov/idl_html_help/COMMON.html
Gökhan Sever
@Gökhan, I'm quite familiar with Fortran (was quite the Fortran wiz back in the 80's and 90's), and with the saying that "you can code Fortran in any language", but the point of that saying is, you **shouldn't** -- whatever language you choose, you should use it properly by that language's idioms and culture. `Bunch`'s 3 (!!!) lines are reusable for a **lot** of extra cases, and give you **proper namespace separation**, which is absolutely crucial to good Python use.
Alex Martelli
@Alex, I didn't know you were a Fortran guru. Times are changing fast when you are in IT I suppose. Who knows maybe you would like to sit in the same class with me and hearing the discussions made around over 50k lines of cloud modeling code written in Fortran and run on clusters.
Gökhan Sever
@Gökhan, I was parallelizing Fortran codes (to run optimally on 6-processor IBM 3090's with 6 Vector Facilities) in the latter part of my career with IBM Research, over 20 years ago -- these days I'm lucky enough to work at Google (where a thousand-servers job is a small one) _and_ to focus on Python (a vastly superior language -- which lets you reuse lower-level stuff coded in Fortran with f2py or pyfort, of course).
Alex Martelli
+3  A: 

If what you want is separation of your constants then put them in another module:

consts.py:

foo = 42
bar = 'quux'

main.py:

import consts

print consts.foo
print consts.bar[::-1]
Ignacio Vazquez-Abrams
I agree that this is best, although I usually make the variable names all `IN_UPPER_CASE` and do `from constants import *`
Eli Courtwright