Why is there no natural syntax for accessing attributes with namesnot being valid identifiers?

  • Thread starter Piotr Dobrogost
  • Start date
R

rusi

Op 04-12-13 13:01, rusi schreef:

No you don't need to change the lexical and grammatical structure of
the language. Changing the characters allowed in identifiers, is not a
change in lexical structure. The only difference in lexical structuring
would be that '-', '>=' and other similars symbols would have to be
treated like keyword like 'from', 'as' etc instead of being recognizable
by just being present.

Well I am mystified…
Consider the string a-b in a program text.
A Cobol or Lisp system sees this as one identifier.
Python, C (and most modern languages) see this ident, operator, ident.

As I understand it this IS the lexical structure of the language and the lexer
is the part that implements this:
- in cobol/lisp keeping it as one
- in python/C breaking it into 3

Maybe you understand in some other way the phrase "lexical structure"?
And the grammatical structure of the language wouldn't change at all.
Sure a-b would now be an identifier and not an operation but that is
of no concern for the parser.

About grammar maybe what you are saying will hold: presumably if the token-set
is the same, one could keep the same grammar, with the differences being
entirely inter-lexeme ones.
 
R

Roy Smith

Tim Roberts said:
Piotr Dobrogost said:
Attribute access syntax being very concise is very often preferred
to dict's interface.

It is not "very concise". It is slightly more concise.

x = obj.value1
x = dct['value1']

You have saved 3 keystrokes. That is not a significant enough savings to
create new syntax. Remember the Python philosophy that there ought to be
one way to do it.

I'll trade typing [ ' ' ] for . any day. Easier to type, easier to
read. It's not just the character count, it's that you need to move
your fingers off the home row (or, at the very least, a big stretch with
your pinkie) to reach the brackets. I suppose that depends on your
particular keyboard layout and typing style/skill.
 
E

Ethan Furman

I think the OP might be after the JavaScript mechanism where an
attribute name can be any string, the indexing brackets are always
available, and the dot notation is available when the attribute name
looks like a simple identifier. That could be made to work. (I'm not
saying should, or should not. Just that it seems technically simple.)

Hm. Can't specific classes be made to behave this way even now by
implementing suitable underscored methods?

No. It is possible to provide attribute access along with key access, but not currently possible to provide attribute
access with quoted values -- which is what the OP wants.
 
A

Antoon Pardon

Op 04-12-13 14:02, rusi schreef:
Well I am mystified…
Consider the string a-b in a program text.
A Cobol or Lisp system sees this as one identifier.
Python, C (and most modern languages) see this ident, operator, ident.

As I understand it this IS the lexical structure of the language and the lexer
is the part that implements this:
- in cobol/lisp keeping it as one
- in python/C breaking it into 3

Maybe you understand in some other way the phrase "lexical structure"?

Yes I do. The fact that a certain string is lexically evaluated differently
is IMO not enough to conclude the language has a different lexical structure.
It only means that the values allowed within the structure are different. What
I see here is that some languages have an other alphabet over which identifiers
are allowed.
About grammar maybe what you are saying will hold: presumably if the token-set
is the same, one could keep the same grammar, with the differences being
entirely inter-lexeme ones.

And the question is. If the token-set is the same, how is then is the lexical
structure different rather than just the possible values associate with the tokens?
 
P

Piotr Dobrogost

It is not "very concise". It is slightly more concise.

x = obj.value1
x = dct['value1']

You have saved 3 keystrokes.

Actually only 1 as you should have compared these:
x = obj.'value-1'
x = dct['value-1']

Unless we compare with what we have now, which gives 9 (without space) or 10 (with space):
x = obj.'value-1'
x = getattr(obj, 'value-1')
That is not a significant enough savings to create new syntax.

Well, 9 characters is probably significant enough saving to create new syntax but saving these characters is only a side effect and is not the most important aspect of this proposal which leads us to the next point.
Remember the Python philosophy that there ought to be one way to do it.

Funny you use this argument against my idea as this idea comes from following this rule whereas getattr goes against it. Using dot is the main syntax to access attributes. Following this, the syntax I'm proposing is much morein line with this primary syntax than getattr is. If there ought to be only one way to access attributes then it should be dot notation.

Regards,
Piotr
 
E

Ethan Furman

If there ought to be only one way to access attributes then it should
be dot notation.

Not "only one way", it's "one obvious way".

The obvious way to deal with objects that do not have legal identifier names is with a dict.
 
P

Piotr Dobrogost

I think random832 is saying that the designed purpose of setattr()
was to dynamically set attributes by name, so they could later be
accessed the traditional way; not designed from the ground-up to
support non-identifier names. But because of the getattr/setattr
machinery (dict key/value pairs), it doesn't prevent you from having
non-identifiers as names as long as you use only the getattr/setattr
method of accessing them.

Right. If there's already a way to have attributes with these "non-standard" names (which is a good thing) then for uniformity with dot access to attributes with "standard" names there should be a variant of dot access allowing to access these "non-standard" named attributes, too.

Regards,
Piotr
 
M

Mark Lawrence

Right. If there's already a way to have attributes with these "non-standard" names (which is a good thing) then for uniformity with dot access to attributes with "standard" names there should be a variant of dot access allowing to access these "non-standard" named attributes, too.

Regards,
Piotr

The obvious thing to do is to either raise this on python ideas, or if
you're that confident about it raise an issue on the bug tracker with a
patch, which would include changes to unit tests and documentation as
well as code, get it reviewed and approved and Bob's your uncle, job
done. Too late for Python 3.4 of course, but no problem for 3.5.
 
M

Mark Lawrence

Not "only one way", it's "one obvious way".

Not "one obvious way" it's "There should be one-- and preferably only
one --obvious way to do it.". Get it right lad :)
 
J

Jerry Hill

Right. If there's already a way to have attributes with these "non-standard" names (which is a good thing) then for uniformity with dot access to attributes with "standard" names there should be a variant of dot access allowing to access these "non-standard" named attributes, too.

Given the follow code, what do you think should print?

class My_Class(object):
pass

bar = 1
my_object = My_Class()
setattr(my_object, 'foo', 10)
setattr(my_object, 'bar', 100)
setattr(my_object, 'foo-bar', 1000)

print(my_object.foo-bar)

Today (in python 3.3), it prints 9, because my_object.foo is 10, the
local variable bar is equal to 1, and 10 minus 1 is 9.. Under your
new proposal, it would print 1000, right? Is there any way for your
proposal to be backwards compatible?
 
P

Piotr Dobrogost

Tim Roberts said:
Piotr Dobrogost <> wrote:
It is not "very concise". It is slightly more concise.
x = obj.value1
x = dct['value1']
You have saved 3 keystrokes. That is not a significant enough savings to
create new syntax. Remember the Python philosophy that there ought to be
one way to do it.

I'll trade typing [ ' ' ] for . any day. Easier to type, easier to
read. It's not just the character count, it's that you need to move
your fingers off the home row (or, at the very least, a big stretch with
your pinkie) to reach the brackets. I suppose that depends on your
particular keyboard layout and typing style/skill.

Very true. Just a remark it's actually trading getattr(o,'x') for o.'x' (saving of 11 keystrokes - don't forget shifts :)) as attribute is quite a different beast then key in a dictionary so comparing this to dict's interfaceis comparing apples to oranges.

Regards,
Piotr
 
E

Ethan Furman

Given the follow code, what do you think should print?

class My_Class(object):
pass

bar = 1
my_object = My_Class()
setattr(my_object, 'foo', 10)
setattr(my_object, 'bar', 100)
setattr(my_object, 'foo-bar', 1000)

print(my_object.foo-bar)

Actually, under his proposal it would be:

print(my_object."foo-bar")

and it would print 1000, while yours would still print 9.
 
N

Neil Cerutti

Right. If there's already a way to have attributes with these
"non-standard" names (which is a good thing)

At best its a neutral thing. You can use dict for the same
purpose with very little effort and no(?) loss of efficiency.
then for uniformity with dot access to attributes with
"standard" names there should be a variant of dot access
allowing to access these "non-standard" named attributes, too.

New syntax needs more than theoretical justifications; it needs
persuasive use cases.

Using invalid identifiers as attributes is generally a bad idea,
not something to do commonly. Your proposed syntax leaves the
distinction between valid and invalid identifiers a problem the
programmer has to deal with. It doesn't unify access to
attributes the way the getattr and setattr do.
 
P

Piotr Dobrogost

not something to do commonly. Your proposed syntax leaves the
distinction between valid and invalid identifiers a problem the
programmer has to deal with. It doesn't unify access to
attributes the way the getattr and setattr do.

Taking into account that obj.'x' would be equivalent to obj.x any attribute can be accessed with the new syntax. I don't see how this is not unified access compared to using getattr instead dot...

Regards,
Piotr
 
T

Terry Reedy

On 12/4/2013 3:07 PM, Piotr Dobrogost wrote:

You have proposed to make non-identifier attribute names 'official',
rather than discouraged, by abbreviating
x = getattr(obj, 'value-1')
or
x = obj.__dict__['value-1'] # implementation detail
as
x = obj.'value-1'

The discussion of enlarging the scope of 'identifier' is not relevant as
you are not proposing that. In particular, you are not asking that
obj.value-1 get the 'value-1' attribute of obj. The discussion of
keystrokes is also a side-track.

What you are proposing, I believe, is a new grammatical category:
attribute-name := identifier or string-literal. This would break the
symmetry of the grammatical form identifier '.' identifier and change it
to the asymmetrical identifier '.' attribute-name, and that is the
problem. Most identifiers are attributes of a namespace and many
attributes are set *and accessed* as undotted names in module or class
code. The symmetry is at least partly inherent and breaking it does not
work very well.
True

To put it another way, how does 'obj' get the non-standard attribute
'value-1', when obj is a module or class? The workaround given above for
module attributes will not work for classes.
Funny you use this argument against my idea as this idea comes from
following this rule whereas getattr goes against it.

Not really. As others have pointed out, getattr is the preferred way to
get the value of an attribute when you have an object with attributes
and a run-time-only reference to the name in a string variable.

It would also be the case that "obj.'value' is obj.value", so the
proposal *would* add duplication.
 
P

Piotr Dobrogost

At best its a neutral thing. You can use dict for the same
purpose with very little effort and no(?) loss of efficiency.

As much as many people in this topic would like to put equal sign between attributes and dictionary's keys they are not the same thing. AFAIK descriptor protocol works only with attributes, right?

Regards,
Piotr
 
D

Dave Angel

Re: Why is there no natural syntax for accessing attributes with
names not being valid identifiers?


Object's attributes and dictionary's keys are quite different
things.

Right. So if you need arbitrary keys, use a dict. Attributes are
keyed by identifiers, which are constrained. No problem.
 
E

Ethan Furman

As much as many people in this topic would like to put equal
sign between attributes and dictionary's keys they are not the
same thing. AFAIK descriptor protocol works only with attributes,
right?

Correct. It is looking very unlikely that you are going to get enough support for this change. Perhaps you should look
at different ways of spelling your identifiers? Why can't you use an underscore instead of a hyphen?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,049
Latest member
Allen00Reed

Latest Threads

Top