12

There is a dictionary in my class with informative, short string constants as keys that identify certain parts of the solution, like "velocity", "death_star_power_output". My colleague suggested that I use VELOCITY="velocity" and DEATH_STAR_POWER_OUTPUT="death_star_power_output" to index into this dictionary throughout the program, because it's the practice.

While I know such practices from other programming languages, where they serve a pragmatic purpose - that is to fail-fast in case of misspelling of the string - in Python it's the same one way or the other. Both:

value = dictionary["death_star_powder_output"] 

and

DEATH_STAR_POWER_OUTPUT="death_star_power_output" [...] value = dictionary[DEATH_STAR_POWDER_OUTPUT] 

will fail at the same time. Please notice the misspelling of POWER as POWDER. Is there some official guideline pertaining to this kind of practice in Python?

5
  • 2
    How are these strings actually used? Personally, if possible, I would get rid of the strings completely and replace them with an enum...CommentedMar 15, 2018 at 17:41
  • They are used only ever as keys in a dictionary. They are descriptive and accurate as of what they represent in it.
    – loa_in_
    CommentedMar 15, 2018 at 19:51
  • In fact they could as well be properties, but declaring those "struct-like" classes that are empty isn't really something I like to have in my projects.
    – loa_in_
    CommentedMar 15, 2018 at 19:52
  • Nor do they fall under namedtuples' umbrella, because their contents actually change.
    – loa_in_
    CommentedMar 15, 2018 at 19:58
  • If they're just used to index a dictionary then I would certainly use an enum instead of strings. Or replace the dictionary with a class containing each of these parameters as a member variable. I'm not sure which is the "Pythonic" approach but a "struct-like" class makes more sense to me if the set of variables won't be changing at run-time, what is your objection to this approach?CommentedMar 16, 2018 at 10:25

3 Answers 3

12

It's not as useful to eschew string literals in Python as it is in other languages, because Python enforces no strict predeclaration of identifiers, but it is still useful.

It's true that if you misspell a constant name in Python, you might not get a warning until run-time. But sufficiently clever analysers can still detect that you are using a variable that doesn't seem to have a declaration, or that you are declaring a constant that doesn't seem to be used. And since tooling support can only become smarter over time, and tool support changes much faster than language standard, it pays to obey conventions that enable better error checking whether it's already there or not.

2
  • The tool support is already there: pyflakes/flake8 can detect many uses of unassigned variables through its syntax-level analysis, and pylint is able to run much more comprehensive checks that also consider imported modules.
    – amon
    CommentedMar 14, 2018 at 12:32
  • This. Your IDE should tell you if you have misspelled variable like DEATH_STAR_POWDER_OUTPUT.
    – Niko Fohr
    CommentedJan 25, 2023 at 12:35
6

In addition to the reasons Kilian Foth gave, one of the most basic, language-agnostic reasons to use constants in the first place is, paradoxically, because it makes code easier to change.

A constant is "constant" with respect to the execution of the program. That is, constants should have values that never programmatically change. Nevertheless, project requirements can and do change, and when they do, all your hard work can be reused without a waste of programmer time and introducing potential bugs.

Whether or not Python specifically receives fail-fast benefits from constants, it at least gets the basic benefits of using constants in general.

    1

    As someone who has used Python since version 1.5, this is "not the practice".

    I can think of some reasons to do things like this. One would be localization. Another would be string re-use.

    In the case of localization, you'd want all your display strings easily accessible to the localization team(s), but these would only be strings that are displayed to the user, not internal strings, like dictionary indices.

    In the case of re-use, you wouldn't want the variable to mirror the entire string, that's rather useless, but something like this might make more sense:

    user_error = "The software has encountered an error, probably your fault" system_error = "This crummy software is bad, and it has hit a problem" 

    And then you might use those variables elsewhere, or multiple times. And the exact message could be changed at a later time without finding every instance throughout the code.

    2
    • Neither case applies for dictionary keys, though.
      – loa_in_
      CommentedMar 15, 2018 at 10:51
    • I didn't see your comments when I answered. I would not use this approach for dictionary keys.
      – jgritty
      CommentedMar 17, 2018 at 22:00

    Start asking to get answers

    Find the answer to your question by asking.

    Ask question

    Explore related questions

    See similar questions with these tags.