27

PEP 8 recommends using a single trailing underscore to avoid conflicts with python keywords, but what about conflicts with module names for standard python modules? Should that also be a single trailing underscore?

I'm imagining something like this:

import time time_ = time.time() 
1
  • 1
    +1 for bringing up PEP 8 - you answered my question with your question by mentioning it! Now I have to go back and rename all my _file and _id local variables as file_ and id_ instead... Commented Jul 2, 2014 at 12:48

2 Answers 2

13

PEP 8 doesn't seem to address it directly.

The trailing underscore is obviously necessary when you're colliding with a keyword, because your code would otherwise raise a SyntaxError (or, if you're really unlucky, compile to mean something completely different than you intended).

So, even in contexts where you have a class attribute, instance attribute, function parameter, or local variable that you want to name class, you have to go with class_ instead.

But the same isn't true for time. And I think in those cases, you shouldn't postfix an underscore for time.

There's precedent for that—multiple classes in the stdlib itself have methods or data attributes named time (and none of them have time_).


Of course there's the case where you're creating a name at the same scope as the module (usually meaning a global variable or function). Then you've got much more potential for confusion, and hiding the ability to access anything on the time module for the rest of the current scope.

I think 90% of the time, the answer is going to be "That shouldn't be a global".


But that still leaves the other 10%.

And there's also the case where your name is in a restricted namespace, but that namespace is a local scope inside a function where you need to access the time module.

Or, maybe, in a long, complicated function (which you shouldn't have any of, but… sometimes you do). If it wouldn't be obvious to a human reader that time is a local rather than the module, that's just as bad as confusing the interpreter.

Here, I think that 99% of the remaining time, the answer is "Just pick a different name".

For example, look at this code:

def dostuff(iterable): time = time.time() for thing in iterable: dothing(thing) return time.time() - time # oops! 

The obvious answer here is to rename the variable start or t0 or something else. Besides solving the problem, it's also a more meaningful name.


But that still leaves the 1%.

For example, there are libraries that generate Python code out of, say, a protocol specification, or a .NET or ObjC interface, where the names aren't under your control; all you can do is apply some kind of programmatic and unambiguous rule to the translated names. In that case, I think a rule that appends _ to stdlib module names as well as keywords might be a good idea.

You can probably come up with other examples where the variable can't just be arbitrarily renamed, and has to (at least potentially) live in the same scope as the time module, and so on. In any such cases, I'd go for the _ suffix.

Sign up to request clarification or add additional context in comments.

3 Comments

So you're saying that if I need to create a local variable in a function I should just use the name time and clobber the package for the rest of that function?
@chappy: Well, no, I think you should "Just pick a different name". And you also should have mostly reasonably short and simple functions, in which case that "clobbering" will probably make no difference—and, more importantly, that non-difference should be obvious to any human reader. On the rare occasions when neither of those applies, then sure, go with time_. But I suspect that will never come up in your entire lifetime of coding.
@chappy: That obviously wasn't clear from my answer, and it should have been, so… let me try to rewrite it.
2

answer according to PEP8

Use a single trailing underscore (as you did for time_).

This is how its mentioned in PEP:

single_trailing_underscore_: used by convention to avoid conflicts with Python keyword, e.g.

tkinter.Toplevel(master, class_='ClassName')

https://peps.python.org/pep-0008/#descriptive-naming-styles

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.