Python - define constant inside function
Asked Answered
K

2

25

Given that there are no real constants in Python, the convention is to name them in CAPS for conveying the intentions.

In following sample code, FIRST and SECOND are constants:

def fibonacci_generator(count):
    FIRST, SECOND = 0, 1
    a, b = FIRST, SECOND
    for _ in range(count):
        yield a
        a, b = b, a + b

print(list(fibonacci_generator(10)))

But for the two constants, PyCharm is giving warning as:

Variable in function should be lowercase

enter image description here

Is there any other correct way to define constants within functions? (Without suppressing the PyCharm warning)

Kain answered 5/9, 2019 at 8:29 Comment(1)
I often like to name some value inside a function in order to be able to use it to simplify expressions later on. When I know I never want to alter that value later on, I find it helpful to be able to mark it as a constant, to enlist the compiler or IDE to warn me if I (or another maintainer) inadvertently alters the initial value. In c/c++ I would mark the variable with const, and in java i would mark it final. These are not 'universal' constants like the gravitational constant, as the value may be specific to each time the function runs. So using a module constant is not helpful.Stroup
B
14

According to PEP8 constants should be defined at the module level:

Constants are usually defined on a module level and written in all capital letters with underscores separating words. Examples include MAX_OVERFLOW and TOTAL.

There is no convention for naming constants inside functions or methods.

You can:

  • Live with the warning, or
  • Suppress it, or
  • Use "normal" lowercase names

In this case, you could also use default arguments without getting a warning but it does seem like an overkill just to get around a PEP8 convention warning:

enter image description here

However, this is counter-productive because you violate one convention in order to not get a warning about violating another.

Baluchistan answered 5/9, 2019 at 8:36 Comment(7)
I would capitalize on the fact that it states constants are to be defined at the module level not any deeper.Cowardice
@Cowardice mentioned twice in my answer. Feel free to edit it if you feel this is not enough :)Baluchistan
I get the idea, that one "should" define constants at the module level as per PEP8. But, the default argument way of suppression is a complete mess and shouldn't even be remotely considered as an option, as it has the potential to change the method's behavior altogether. If there is no convention for function level constants in PEP8, I would consider it a shortfall actually, that should be rectified by the committee because the other 3 options you suggested are all forcing the developer to deal with limitation, why should we?Kain
@SagarGuptaFTW This is exactly why PEP8 is a convention (ie a recommendation) that generates warnings rather than syntax errors. You may decide to ignore parts of it (or all of it)Baluchistan
@Baluchistan I have this weird compulsion to code the right way, so this situation irks me :D. I don't want to define constant at the top, because I believe objects should be as tightly scoped as possible. And I also don't want to use lower casing for a constant, no sir. Warning suppression is all I'm left with, don't want to do that either unless it is the last resort. Let's wait for more inputs. I hope that question is meaningful enough to be considered.Kain
I often name a value inside a function, to simplify expressions later on. If I know I never want to alter it I mark it as a constant, to enlist the compiler or IDE to warn me if I (or another maintainer) inadvertently alters the initial value. (AKA defensive programming or paranoia). In c/c++ I would just mark the variable with const, and in java i would mark it final. Such variables are not 'universal' constants like the gravitational constant, as the value may be specific to each time the function runs. Using a module constant is not helpful. So... Any other way in Python?Stroup
@Stroup Consider using mypy For further details I think it'd be better if you ask a new questionBaluchistan
P
10

Besides what have been proposed by @DeepSpace, other potential choices are (1) using underscore-prefixed variable names such as _FIRST, _SECOND, etc.; (2) writing a class instead and make the constants class-level constants.

Psychic answered 5/9, 2019 at 17:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.