update from the author
This commit is contained in:
parent
f7cee114e2
commit
d715130cfe
175
pep-0363.txt
175
pep-0363.txt
|
@ -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,74 +136,12 @@ 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
|
||||
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue