Write a snippet that checks a list of candidate names for validity and reserved-word status, and shows the error Python raises for a bad name.
An identifier in Python is any name that you give to something. That covers variables, functions, classes, methods, and module names. The rules are short enough to state in full. A name has to start with a letter or an underscore. Every character after that has to be a letter, a digit, or an underscore. The name cannot be a keyword. Python treats upper and lower case as different, so Name and name are two different identifiers. And since Python 3, letters outside the plain ASCII range are allowed, so café is a legal identifier.
You can check all of this in your program instead of guessing.
import keyword
candidates = ['user_name', '2fast', 'class', 'my-name', '_private', 'café']
for name in candidates:
print(repr(name), 'valid:', name.isidentifier(), 'reserved:', keyword.iskeyword(name))
# This is the message the interpreter gives you itself.
try:
compile('class = 1', '', 'exec')
print('no error')
except SyntaxError as error:
print('SyntaxError:', error.msg)
The first block reports user_name, _private, and café as valid. It reports 2fast and my-name as invalid, because they break the rules about which characters are allowed. It reports class as the right shape but reserved. The compile call then raises the interpreter's own message, which says that you cannot assign to class.
Notice that isidentifier() only checks the shape of the name. It returns True for class, and that is why the keyword check has to be a separate step. In a linter or in a form, the two checks are always done together.