Atoms, Identifiers, and Primaries

Steven D'Aprano steve+comp.lang.python at pearwood.info
Wed Apr 17 07:43:18 EDT 2013


On Tue, 16 Apr 2013 19:57:25 -0700, Bruce McGoveran wrote:

> These are terms that appear in section 5 (Expressions) of the Python
> online documentation.  I'm having some trouble understanding what,
> precisely, these terms mean.  I'd appreciate the forum's thoughts on
> these questions:
> 
> 1.  Section 5.2.1 indicates that an identifier occurring as an atom is a
> name.  However, Section 2.3 indicates that identifiers are names.  My
> question:  can an identifier be anything other than a name?

Yes and no.

According to the Python grammar as documented, no, identifiers are just 
another name for, er, name.

But according to common practice, yes, we call many things identifiers:

x  # a bare name, or "identifier" according to the grammar

x.attr  # name with an attribute, or "attributeref"

x[key]  # name with a subscript, or "subscription"

x[5]  # name with an indexed subscript, or "slicing"

x[start:stop:step]  # name with a slice subscript



> 2.  Section 5.3 defines primaries as the most tightly bound operations
> of Python.  What does this mean?

It means that primaries are evaluated at the highest priority. For 
example, given:

x.a+b

that is evaluated as:

(x.a) + b

rather than:

x . (a+b)


In particular, if you have a variable:

name = "Fred"

then x.name will look for an attribute "name", *not* x.Fred.


> In particular, if an atom is a
> primary, what operation is the atom performing that leads to the label
> "most tightly bound"?  To put it a different way, I think of atoms as
> things (i.e. identifiers).

Correct.


> The documentation makes me think atoms
> actually do something, as opposed to being things (I think I have in my
> mind the difference between a noun and a verb as I write this).

The only thing they do is be evaluated.




> 3.  Section 5.3.1 offers this definition of an attributeref:
>     attributeref ::= primary "." identifier
> 
> Now, I was at first a little concerned to see the non-terminal primary
> on the right hand side of the definition, since primary is defined to
> include attributeref in section 5.3 (so this struck me as circular).  Am
> I correct in thinking attributeref is defined this way to allow for
> situations in which the primary, whether an atom, attributeref (example:
>  an object on which a method is called that returns another object),
> subscription, slicing, or call, returns an object with property
> identifier?

Yes. It means you can write things like this:

module.Class.method()[0](arg).attr.name[2]['spam'].aardvark()

and have it evaluated from left to right.



With respect, I think you may be confusing yourself unnecessarily with an 
excessive concern for the formal grammar of Python. You may find it makes 
a lot more sense in practice than it makes in theory. I strongly 
recommend you open up an interactive interpreter and just play around 
with the syntax and see what happens.




-- 
Steven



More information about the Python-list mailing list