python - Pylint showing invalid variable name in output - Stack Overflow
python - Pythonically check if a variable name is valid - Stack Overflow
validation - How do I convert a string to a valid variable name in Python? - Stack Overflow
Website to check Illegal variable names or keywords Python - Stack Overflow
Videos
I found lists of "reserved keywords" for python, but there seems to be other words which python lets you use for variable names, but maybe it's better not to use these names?
Such as 'file' or 'sum,' etc
Is there a complete list of such words?
As your code is not contained in a class or function it is expecting those variables to be constants and as such they should be uppercase.
You can read PEP8 for further information.
EDIT: As others have mentioned, pylint expects that global variables should be UPPERCASE. If the warnings really bother you, you can circumvent them by wrapping small snippets like this in a main()-function and then use the if __name__ == "__main__"-convention. Or if you care, you can modify the regular expressions that pylint uses to validate variable names.
From the developers of Pylint.
In this case Pylint is telling me that those variables appear to be constants and should be all UPPERCASE. This rule is in fact a naming convention that is specific to the folks at Logilab who created Pylint. That is the way they have chosen to name those variables. You too can create your own in-house naming conventions but for the purpose of this tutorial, we want to stick to the PEP-8 standard. In this case, the variables I declared should follow the convention of all lowercase. The appropriate rule would be something like: "should match [a-z_][a-z0-9_]{2,30}$". Notice the lowercase letters in the regular expression (a-z versus A-Z)
You can test it by running:
pylint --const-rgx='[a-z_][a-z0-9_]{2,30}$' x.py
In Python 3 you can use str.isidentifier() to test whether a given string is a valid Python identifier/name.
>>> 'X'.isidentifier()
True
>>> 'X123'.isidentifier()
True
>>> '2'.isidentifier()
False
>>> 'while'.isidentifier()
True
The last example shows that you should also check whether the variable name clashes with a Python keyword:
>>> from keyword import iskeyword
>>> iskeyword('X')
False
>>> iskeyword('while')
True
So you could put that together in a function:
from keyword import iskeyword
def is_valid_variable_name(name):
return name.isidentifier() and not iskeyword(name)
Another option, which works in Python 2 and 3, is to use the ast module:
from ast import parse
def is_valid_variable_name(name):
try:
parse('{} = None'.format(name))
return True
except SyntaxError, ValueError, TypeError:
return False
>>> is_valid_variable_name('X')
True
>>> is_valid_variable_name('123')
False
>>> is_valid_variable_name('for')
False
>>> is_valid_variable_name('')
False
>>> is_valid_variable_name(42)
False
This will parse the assignment statement without actually executing it. It will pick up invalid identifiers as well as attempts to assign to a keyword. In the above code None is an arbitrary value to assign to the given name - it could be any valid expression for the RHS.
EDIT: this is wrong and implementation dependent - see comments.
Just have Python do its own check by making a dictionary with the variable holding the name as the key and splatting it as keyword arguments:
def _dummy_function(**kwargs):
pass
def is_valid_variable_name(name):
try:
_dummy_function(**{name: None})
return True
except TypeError:
return False
Notably, TypeError is consistently raised whenever a dict splats into keyword arguments but has a key which isn't a valid function argument, and whenever a dict literal is being constructed with an invalid key, so this will work correctly on anything you pass to it.
Well, I'd like to best Triptych's solution with ... a one-liner!
>>> def clean(varStr): return re.sub('\W|^(?=\d)','_', varStr)
...
>>> clean('32v2 g #Gmw845h$W b53wi ')
'_32v2_g__Gmw845h_W_b53wi_'
This substitution replaces any non-variable appropriate character with underscore and inserts underscore in front if the string starts with a digit. IMO, 'name/with/slashes' looks better as variable name name_with_slashes than as namewithslashes.
According to Python, an identifier is a letter or underscore, followed by an unlimited string of letters, numbers, and underscores:
import re
def clean(s):
# Remove invalid characters
s = re.sub('[^0-9a-zA-Z_]', '', s)
# Remove leading characters until we find a letter or underscore
s = re.sub('^[^a-zA-Z_]+', '', s)
return s
Use like this:
>>> clean(' 32v2 g #Gmw845h$W b53wi ')
'v2gGmw845hWb53wi'
You can test whether something is a keyword or not using the keyword module
>>> import keyword
>>> keyword.iskeyword("pass")
True
>>> keyword.iskeyword("not_pass")
False
https://docs.python.org/2/library/keyword.html
This module allows a Python program to determine if a string is a keyword.
keyword.iskeyword(s)
Return true if s is a Python keyword.
Some variable names are illegal in Python because of it being a reserved word.
From the keywords section in the Python docs:
The following identifiers are used as reserved words, or keywords of the language, and cannot be used as ordinary identifiers. They must be spelled exactly as written here:
# Complete list of reserved words
and
del
from
not
while
as
elif
global
or
with
assert
else
if
pass
yield
break
except
import
print
class
exec
in
raise
continue
finally
is
return
def
for
lambda
try
True # Python 3 onwards
False # Python 3 onwards
None # Python 3 onwards
nonlocal # Python 3 onwards
async # in Python 3.7
await # in Python 3.7
So, you cannot use any of the above identifiers as a variable name.