4

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?

  • 1
    How are these strings actually used? Personally, if possible, I would get rid of the strings completely and replace them with an enum... – Sean Burton Mar 15 '18 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_ Mar 15 '18 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_ Mar 15 '18 at 19:52
  • Nor do they fall under namedtuples' umbrella, because their contents actually change. – loa_in_ Mar 15 '18 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? – Sean Burton Mar 16 '18 at 10:25
7

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.

  • 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 Mar 14 '18 at 12:32
  • I upvoted this answer only because it mentions tooling support. Also extended to IDE support and help offered by these in this situation. – loa_in_ Mar 15 '18 at 19:56
1

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.

0

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.

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.