Why can't name attributes be Python keywords?

There is a restriction on the attribute access syntax in Python (at least in the implementation of CPython 2.7.2):

>>> class C(object): pass >>> o = C() >>> ox = 123 # Works >>> o.if = 123 o.if = 123 ^ SyntaxError: invalid syntax 

My question is twofold:

  • Is there a fundamental reason why using the Python keyword attribute names (as in o.if = 123 ) is forbidden?
  • Is / where is the specified restriction on attribute names documented?

It would be wise to do o.class = … in one of my programs, and I'm a little disappointed that I can't do this ( o.class_ will work, but it doesn't look so simple).

PS . Obviously, the problem is that if and class are Python keywords. The question is why the use of keywords as attribute names would be prohibited (I do not see any ambiguity in the expression o.class = 123 ) and whether this is documented.

+8
python attributes syntax-error
source share
3 answers

Since the parser is simpler when keywords are always keywords and not contextual (for example, if is a keyword when at the operator level, but just an identifier, when inside an expression is for if , it will be double, X if C else Y , and for used in list expressions and generator expressions).

Thus, the code does not even reach the point where there is access to the attribute, it is simply rejected by the parser, just like an incorrect indent (that's why it is a SyntaxError , not an AttributeError or something else). It does not distinguish whether you use if the attribute name, variable name, function name, or type name. It can never be an identifier, simply because the parser always assigns it a keyword tag and makes it a different marker than identifiers.

This is the same in most languages, and the language grammar (+ lexer specification) is the documentation for this. The language specifies this explicitly . It also does not change in Python 3.

Also, just because you can use setattr or __dict__ to create an attribute with a reserved name does not mean what you need. Do not force yourself / the API user to use getattr instead of naturally accessing attributes. getattr should be reserved if access to the variable attribute name is required.

+7
source share

I do not think that if can be used as a variable name or attribute (explicitly), since it is a keyword.

However, you can use setattr and getattr to get around this in a dirty way.

 >>> class C(object): pass ... >>> o = C() >>> setattr(o, 'if', 123) >>> getattr(o, 'if') 123 
+3
source share

Because if is a keyword. You have similar problems with o.while and o.for :

 pax> python >>> class C(object): pass ... >>> o = C() >>> o.not_a_keyword = 123 >>> o.if = 123 File "<stdin>", line 1 o.if = 123 ^ SyntaxError: invalid syntax >>> o.while = 123 File "<stdin>", line 1 o.while = 123 ^ SyntaxError: invalid syntax >>> o.for = 123 File "<stdin>", line 1 o.for = 123 ^ SyntaxError: invalid syntax 

Other keywords in Python can be obtained using:

 >>> import keyword >>> keyword.kwlist ['and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'exec', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'not', 'or', 'pass', 'print', 'raise', 'return', 'try', 'while', 'with', 'yield'] 

Normally you should not use the keyword as a variable name in Python.

I would suggest choosing a more descriptive name, for example iface , if it is an interface, or infld for an input field, etc.

As for your question about why keywords are not allowed, this greatly simplifies parsers if lexical elements are not contextual. It is necessary to treat the lexical if token as a keyword in some places, and the identifier in others will introduce complexity that is not needed if you choose your identifiers more wisely.

For example, the C ++ operator:

 long int int = char[new - int]; 

can be (with little difficulty) evaluated using a complex parser based on where these lexical elements originate (and what exists on both sides of them). But, at least in part, in the interest of simplicity (and readability) this is not done.

+1
source share

All Articles