views:

48

answers:

4

Example code from a module:

somevar = "a"

def myfunc(somevar = None):
    # need to access both somevars ???
    # ... if somevar was specified print it or use the global value
    pass

if __name__ == '__main__':
    somevar = "b" # this is just for fun here
    myfunc("c")
    myfunc() # should print "a" (the value of global variable)

There are at least two reasons for using the same name:educational (to learn how to use local/globals) and usage in modules.

Let say that this code is part of your module: mymodule and you want to do things like:

import mymodule

mymodule.samevar = "default"
...
mymodule.myfunc(somevar = "a")
...
mymodule.myfunc()

As you can imagine in this example is simplified, imagine that somevar parameter is one of many optional parameters and that myfunc is called in many places.

A: 

Two solutions:

  1. Rename the variable, ie to somevar_.
  2. Move the global to a different module. You can write a module myappdefaults

    import myappdefaults
    print myappdefaults.somevar
    
THC4k
+1  A: 

Why does you local variable have to have the same name as the global variable? Renaming one of them seems like a simple solution. Another option is to pass the global variable in as a parameter, but this will still just give you a different variable name to access the save value.

unholysampler
+5  A: 

By far the best approach, as the other answers say, is to avoid this very, very bad design: just don't use the same names for two different things!

If you're locked into this terrible design, maybe because your company's Supreme Architect decreed it and it's just non-negotiable (e.g., there's tons of customer code relying on the names of both the global and the parameter), the first order of business for you is to make sure your resume is up to date, print it on the best printer, and start getting in touch with members of your social network to look for a job at a place that's run more sensibly; next, to avoid losing health insurance until a better job is found, try

def myfunc(somevar = None):
    if somevar is None:
        print globals().get('somevar')
    else:
        print somevar

I've also renamed your mufunc to myfunc because that's the name it's being called with (though given the incredibly bad design your hypothetical Supreme Architect seems to be able to perpetrate, maybe he's also specified that the function be called by a different name from the one it's defined with? seems to go with the systematic name conflict this hypothetical but already pretty hateful guy is assumed to have foisted on you!-).

Alex Martelli
You are really funny and helpful! I corrected the typos from the example. Now I will update the question and explain you why I was interested about using the same name.
bogdan
@bogdan, thanks for the kudos _and_ the clarification. In Python idiom, when a value must have a general default value but can be overridden per-call with specific values, the former is usually named with a `default_` prefix -- for example, see the socket module, `getdefaulttimeout` and `setdefaulttimeout` functions and the `timeout` named parameter to various functions (using getter and setter functions in this case, rather than "just a global variable", is also common, since _modules_ can't use the `property` built-in, which is what lets you always avoid getters/setters in _classes_).
Alex Martelli
A: 

This is the correct way to do things.

somevar = "a"

def mufunc(_somevar = None):
    global somevar
    if _somevar:
        print _somevar
    else:
        print somevar

if __name__ == '__main__':
    global somevar
    somevar = "b"
    myfunc("c")
    myfunc() $ should print "c"
Matt Williamson