update from the author

This commit is contained in:
David Goodger 2007-02-20 03:30:58 +00:00
parent f7cee114e2
commit d715130cfe
1 changed files with 78 additions and 99 deletions

View File

@ -2,12 +2,12 @@ PEP: 363
Title: Syntax For Dynamic Attribute Access
Version: $Revision$
Last-Modified: $Date$
Author: Ben North <ben at redfrontdoor.org>
Status: Draft
Author: Ben North <ben@redfrontdoor.org>
Status: Rejected
Type: Standards Track
Content-Type: text/plain
Created: 29-Jan-2007
Post-History:
Post-History: 12-Feb-2007
Abstract
@ -28,13 +28,6 @@ Abstract
z = getattr(getattr(y, 'foo_%d' % n), 'bar_%s' % s)
Note
I wrote this patch mostly to advance my own understanding of and
experiment with the python language, but I've written it up in the
style of a PEP in case it might be a useful idea.
Rationale
Dictionary access and indexing both have a friendly invocation
@ -64,18 +57,17 @@ Rationale
x = getattr(y, 'foo_%d' % n, 0)
This PEP describes a new syntax for dynamic attribute access ---
"x.(expr)" --- with examples given in the Abstract above. The new
syntax also allows the provision of a default value in the "get"
case, as in:
"x.(expr)" --- with examples given in the Abstract above.
(The new syntax could also allow the provision of a default value in
the "get" case, as in:
x = y.('foo_%d' % n, None)
This 2-argument form of dynamic attribute access is not permitted as
the target of an (augmented or normal) assignment. Also, this part
of the new syntax was not as well received [6] in initial
discussions on python-ideas, and I agree that it does not fit so
cleanly. I'm happy to prepare a revised PEP/patch without the
2-argument form if the consensus is that this would be preferred.
This 2-argument form of dynamic attribute access would not be
permitted as the target of an (augmented or normal) assignment. The
"Discussion" section below includes opinions specifically on the
2-argument extension.)
Finally, the new syntax can be used with the "del" statement, as in
@ -144,80 +136,18 @@ Performance Impact
be a performance penalty of around 1% in the pystones score with the
patched version. One suggestion is that this is because the longer
main loop in ceval.c hurts the cache behaviour, but this has not
been confirmed. (Maybe a tool like valgrind [2] could help here?)
been confirmed.
On the other hand, measurements suggest a speed-up of around 40--45%
for dynamic attribute access.
Discussion To Date
Initial posting of this PEP in draft form was to python-ideas on
20070209 [4], and the response was generally positive:
I've thought of the same syntax. I think you should submit this
to the PEP editor and argue on Python-dev for its inclusion in
Python 2.6 -- there's no benefit that I see of waiting until
3.0. --- Guido van Rossum [5]
Wow! I have to say this is a compelling idea. The syntax is a
bit foreign looking, but [...] I feel like I could learn to like
it anyway. --- Greg Falcon [6]
I look forward to seeing this in Python 2.6. --- Josiah
Carlson, further down the thread [8]
with Greg Falcon expressing the reservations about the 2-argument
form already noted above, and Josiah Carlson raising a query about
performance:
My only concern with your propsed change is your draft
implementation. [...] Specifically, your changes [...] may
negatively affect general Python performance. --- Josiah
Carlson [7]
Some initial measurements (see above) suggest the performance
penalty is small, and Josiah Carlson said of such cost that it
"isn't really substantial". [8]
Questions To Be Resolved
* Whether to allow the 2-argument form for default arguments.
* Whether the performance impact is real; whether it is acceptable;
whether alternative implementations might improve this aspect.
Alternative Syntax For The New Feature
Other syntaxes could be used, for example braces are currently
invalid in a "trailer", so could be used here, giving
x{'foo_%d' % n} += 1
My personal preference is for the
x.('foo_%d' % n) += 1
syntax though: the presence of the dot shows there is attribute
access going on; the parentheses have an analogous meaning to the
mathematical "work this out first" meaning. This is also the
syntax used in the language Matlab [1] for dynamic "field" access
(where "field" is the Matlab term analogous to Python's
"attribute").
Discussions on python-ideas (see above) made no comment on the brace
alternative, and the .() notation was well-enough received, so the
brace alternative should be considered rejected, I think.
Error Cases
Only strings are permitted as attribute names, so for instance the
following error is produced:
>>> x.(99) = 8
>>> x.(99) = 8
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: attribute name must be string, not 'int'
@ -233,29 +163,78 @@ Draft Implementation
compile.c, and three new opcodes (load/store/del) with
accompanying changes to opcode.h and ceval.c. The patch consists
of c.180 additional lines in the core code, and c.100 additional
lines of tests. It is available as sourceforge patch #1657573 [3].
lines of tests. It is available as sourceforge patch #1657573 [1].
Mailing Lists Discussion
Initial posting of this PEP in draft form was to python-ideas on
20070209 [2], and the response was generally positive. The PEP was
then posted to python-dev on 20070212 [3], and an interesting
discussion ensued. A brief summary:
Initially, there was reasonable (but not unanimous) support for the
idea, although the precise choice of syntax had a more mixed
reception. Several people thought the "." would be too easily
overlooked, with the result that the syntax could be confused with a
method/function call. A few alternative syntaxes were suggested:
obj.(foo)
obj.[foo]
obj.{foo}
obj{foo}
obj.*foo
obj->foo
obj<-foo
obj@[foo]
obj.[[foo]]
with "obj.[foo]" emerging as the preferred one. In this initial
discussion, the two-argument form was universally disliked, so it
was to be taken out of the PEP.
Discussion then took a step back to whether this particular feature
provided enough benefit to justify new syntax. As well as requiring
coders to become familiar with the new syntax, there would also be
the problem of backward compatibility --- code using the new syntax
would not run on older pythons.
Instead of new syntax, a new "wrapper class" was proposed, with the
following specification / conceptual implementation suggested by
Martin von Loewis:
class attrs:
def __init__(self, obj):
self.obj = obj
def __getitem__(self, name):
return getattr(self.obj, name)
def __setitem__(self, name, value):
return setattr(self.obj, name, value)
def __delitem__(self, name):
return delattr(self, name)
def __contains__(self, name):
return hasattr(self, name)
This was considered a cleaner and more elegant solution to the
original problem. (Another suggestion was a mixin class providing
dictionary-style access to an object's attributes.)
The decision was made that the present PEP did not meet the burden
of proof for the introduction of new syntax, a view which had been
put forward by some from the beginning of the discussion. The
wrapper class idea was left open as a possibility for a future PEP.
References
[1] Using Dynamic Field Names :: Data Types (MATLAB Programming)
http://www.mathworks.com/access/helpdesk/help/techdoc/matlab_prog/f2-41859.html
[2] Valgrind: "suite of tools for debugging and profiling Linux programs"
http://www.valgrind.org/
[3] Sourceforge patch #1657573
[1] Sourceforge patch #1657573
http://sourceforge.net/tracker/index.php?func=detail&aid=1657573&group_id=5470&atid=305470
[4] http://mail.python.org/pipermail/python-ideas/2007-February/000210.html
[2] http://mail.python.org/pipermail/python-ideas/2007-February/000210.html
and following posts
[5] http://mail.python.org/pipermail/python-ideas/2007-February/000211.html
[6] http://mail.python.org/pipermail/python-ideas/2007-February/000212.html
[7] http://mail.python.org/pipermail/python-ideas/2007-February/000213.html
[8] http://mail.python.org/pipermail/python-ideas/2007-February/000227.html
[3] http://mail.python.org/pipermail/python-dev/2007-February/070939.html
and following posts
Copyright