[Tutor] Questions about Functions
Jeff Shannon
jeff@ccvcorp.com
Tue Feb 18 16:20:07 2003
bob smith wrote:
> Hi. Im learning Python and like it very much so far, but I have some
> questions when it comes to functions.
>
> Question #1
> --------------
> Whats wrong with passing a variable to a function that receives it
> with the same name?
The only problem here is that it's possible that you'll lose track of
the fact that they are, in fact, two separate variables. You might, for
instance, change 'value' in your function, and then be surprised by the
fact that the global 'value' is not updated. But if it's clear in your
mind that when you're inside a function, you're in a whole different
world (well, different namespace), then there's no problem. (At least,
no problem until someone *else* goes to modify your code and gets
surprised by this...) But this is strictly a programmer-psychology
issue, and not a technical issue.
> Question #2
> --------------
> Is it considered bad programming to access (and only access) global
> variables in functions, thus treating them as global constants?
The problem here is that functions (ideally) should be able to operate
identically in a variety of contexts, and thus functions should be as
self-contained as possible. If your function relies on global constants,
and then you have another module that needs the same function, you have
to ensure that all the same global constants are set up in that other
module.
> Since I cant assign a new value to CONSTANT in func(), does this mean
> that Python encourages the use of global constants used like this?
You *can* actually assign a new value to CONSTANT -- except that it
creates a new local variable that shadows your global constant, with
potentially confusing results.
> It seems like a good idea to me, (especially if CONSTANT is needed in
> other functions in the program) but you hear the mantra dont use
> global variables so much that Im not sure if this is considered poor
> programming.
Here's the rub -- using constants like this *is* a very useful thing,
and sometimes it really is the best option. Certainly using global
constants is a lot less hazardous than using global "normal" variables,
and as you say, if the constant is needed in a wide variety of places, a
global constant is probably better than a dozen local constants (which
would be a nightmare to keep in sync if the value needs tweaked). In
programs that are large enough to have this issue, I'll usually create a
separate constants.py that does nothing but define these constants.
Then, every other module that needs to use the constants can 'import
constants; print constants.CONSTANT' or equivalent. This gives me the
practical value of having global constants available, but still keeps
them (relatively) isolated in their own playground.
> Question #3
> --------------
> If you know your program is not going to be imported (only run as a
> stand-alone program) do you ever need to consider having this kind of
> thing:
>
> if __name__ == __main__: main()
If you're absolutely positive that your script will never be used as a
module somewhere else, then this isn't necessary. The catch is that it
often happens that a function that you once thought would never be
needed elsewhere will suddenly become a quick solution to a new problem
elsewhere, and you'll find yourself wanting to import that "only ever
stand-alone" program.
The other point here is that this convention supports a design practice.
When I'm writing a program, I mentally break the problem down into
little pieces, and then I start writing a series of functions (or a set
of classes) that'll solve each of those pieces. Once I have the
low-level problems solved, I start tying those bits together with
higher-level functions, until I have something like a main() function
that solves the whole problem. So the 'if __name__ == __main__:'
convention fits well with the way that I work. If I were to approach a
problem with the thought of *not* using this convention, then I'd be
tempted to write a much more linear program (as opposed to a small
heirarchy of classes and functions). This is fine for very small
scripts, usually, but becomes increasingly difficult to follow as the
size of the program grows. And, of course, even very small programs have
a tendency to grow in size and complexity... so it seems best to start
off in the right direction to begin with.
Hope this makes a few things more clear.
Jeff Shannon
Technician/Programmer
Credit International