If I look in python code and sometimes maybe also in C codes, there is often two variables with the same name except for the underscore. For example two variables
variable1 data; variable2 _data;
Why is it like that and what is the background?
Software Engineering Stack Exchange is a question and answer site for professionals, academics, and students working within the systems development life cycle. It only takes a minute to sign up.Sign up to join this community
For the case of two variable names that only differ by one leading underscore, I think the answer boils down to "the programmer thought it made the code more readable". Whether it actually makes the code more readable may be debatable, but sometimes it can make sense for tightly coupled variables.
For example, you may have a function that takes an argument that you apply some small transformation to before proceeding. Except for the transformation, the variables will contain identical information.
def some_function(foobar): _foobar = foobar.lower() if _foobar == "whatever": ...
If I had to give you a rule of thumb for how to interpret it, I would say it's probably safe to assume the variable with an underscore contains data that is only slightly different from the 'real' value.
If your question is specifically about why someone would use a leading underscore in python, PEP8 contains the official naming standards. Included in those naming standards are rules for leading and trailing underscores.
I can't speak to Python.
In the case of C, identifiers with leading underscores are supposed to be reserved for use by the implementation:
7.1.3 Reserved identifiers
1 Each header declares or defines all identifiers listed in its associated subclause, and optionally declares or defines identifiers listed in its associated future library directions subclause and identifiers which are always reserved either for any use or for use as file scope identifiers.
— All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use.
— All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces.
— Each macro name in any of the following subclauses (including the future library directions) is reserved for use as specified if any of its associated headers is included; unless explicitly stated otherwise (see 7.1.4).
— All identifiers with external linkage in any of the following subclauses (including the future library directions) and errno are always reserved for use as identifiers with external linkage.184)
— Each identifier with file scope listed in any of the following subclauses (including the future library directions) is reserved for use as a macro name and as an identifier with file scope in the same name space if any of its associated headers is included.
2 No other identifiers are reserved. If the program declares or defines an identifier in a context in which it is reserved (other than as allowed by 7.1.4), or defines a reserved identifier as a macro name, the behavior is undefined.
IOW, if you write any C code, you should not use leading underscores for your own identifiers (variable names, function names, and
enum tag names); if you do, you run a slight risk of a name collision with an identifier used by the implementation during translation. For example, if you define a function named
_write, this may conflict with a predefined function
_write that's used by the
printf implementation in the standard library.
Since the behavior on declaring or using a reserved identifier is undefined, the compiler is not obligated to issue any diagnostics; you won't know that there's a problem (if there is one) until runtime, and that problem may be fairly subtle and hard to diagnose. The compilers I'm familiar with won't issue any diagnostics or fail to translate the code.
Note that there's nothing magic about the underscore itself - it's just another character that you can use in an identifier. The only real difference between
data is that they are distinct names; the underscore doesn't add any meaning beyond this. Again, the intent is that names with leading underscores are reserved for use by the implementation, but the compiler typically doesn't enforce this during translation.