6

When declaring a constant that is only used one function, should that variable be declared locally since it is only used by that function, or globally since it is never going to change?

IE which is better:

CONSTANT = (1, 3, 5, 8)

##SOME OTHER CODE HERE

def function1(arg):
    if arg in CONSTANT:
        do something

or:

def function1(arg):
    CONSTANT = (1, 3, 5, 8)
    if arg in CONSTANT:
        do something

I know there isn't a lot of difference between these two, but I just wanted to know which of the two practices is preferred since I'm just starting out and want to form good habits.

user2236076
  • 154
  • 1
  • 2
  • 8
  • 1
    Good question. :) But is `CONSTANT` used more than once? the example suggests that no, but you might want to clarify this. If you use it only once, there is almost no need to give it a name, so you might want to show that you really intend to use it many times in the function. – Eric O. Lebigot Apr 06 '13 at 13:25
  • Personally, I prefer naming things even when I don't think I'm going to use them twice, usually with a nice comment explaining what the constant means. I'm a big proponent of not using literals in my expressions, *especially* if they're used more than once. But in cases where they are used exactly once, I can see it your way. – acjay Apr 06 '13 at 14:16

3 Answers3

4

I would keep it local. You can always just move it global in the future if you need to, or share it between functions by making them methods in a class and turning the constant into a class variable. In these situations, generally speaking, the more local, the better, and best is to hide implementation information within your functions, as in your second example. It doesn't make a huge difference here, but as your projects get bigger, maintainability and modularity will be sustained.

acjay
  • 34,571
  • 6
  • 57
  • 100
1

I would put them global because:

  1. Your variables are constants
  2. In Python, global scope is encapsulated in the module namespace, meaning that your variable is in fact only global inside the module.
  3. If you call your function a lot of times, and put your constants local to it, it would reallocate them each time your call the function.
  4. Then you can share your constants between different functions.

However, if you move to Object Oriented Programming, then I would put the constants as class variables.

Charles Brunet
  • 21,797
  • 24
  • 83
  • 124
  • 1
    The constants are *not* reallocated every time. They are allocated once and referred to by reference. – Dietrich Epp Apr 06 '13 at 13:16
  • 1
    For (1), not sure I get your point. For (2), sure, module variables aren't "global" like the built-ins, but that's kind of beside the point. The same basic arguments against truly global variables apply at any level of scope above local, just to a lesser extent. Extend this logic to a project with hundreds of functions and you start having a mess of variables that aren't really close to the actual code that is concerned with them. Function start disappearing, leaving their unattached constants behind. To me, (3) is premature optimization and (4) is YAGNI. – acjay Apr 06 '13 at 14:11
0

I would say that what is best depends on the situation.

If execution time is not an issue, then having the constant be loaded into a new variable each time does not waste much time. This has the obvious advantage of showing explicitly where in your code the constant is used.

Otherwise, a global is fine, but I would only do this for optimization purposes. If I think of it, optimization is the only reason why I ever asked myself the same question as you.

There might be other good reasons to use a global:

  • if the user of your program often needs to change its value in the code and you don't want to parse program arguments,
  • if other programs need to access it,
  • etc.

In conclusion, I would say: do what you feel is best, but try to encapsulate things as much as reasonably possible where they belong (locals are to be preferred to globals).

Eric O. Lebigot
  • 91,433
  • 48
  • 218
  • 260