Moving this PEP back to Draft after some internal discussions raised
more problems with method attributes as previously proposed. Now, setting attributes on either bound or unbound methods will be disabled for Python 2.1, but potentially re-enabled for Python 2.2 using a different mechanism. Getting method attributes is unchanged for Python 2.1 (but may be elaborated in Python 2.2).
This commit is contained in:
parent
49e6e98d67
commit
b075e5b7ae
85
pep-0232.txt
85
pep-0232.txt
|
@ -2,11 +2,11 @@ PEP: 232
|
|||
Title: Function Attributes
|
||||
Version: $Revision$
|
||||
Author: barry@digicool.com (Barry A. Warsaw)
|
||||
Status: Final
|
||||
Status: Draft
|
||||
Type: Standards Track
|
||||
Created: 02-Dec-2000
|
||||
Python-Version: 2.1
|
||||
Post-History:
|
||||
Python-Version: 2.1 / 2.2
|
||||
Post-History: 20-Feb-2001
|
||||
|
||||
|
||||
Introduction
|
||||
|
@ -23,12 +23,12 @@ Introduction
|
|||
|
||||
Background
|
||||
|
||||
Functions and methods already have a number of attributes, some of
|
||||
which are writable, e.g. func_doc, a.k.a. func.__doc__. func_doc
|
||||
has the interesting property that there is special syntax in
|
||||
function (and method) definitions for implicitly setting the
|
||||
attribute. This convenience has been exploited over and over
|
||||
again, overloading docstrings with additional semantics.
|
||||
Functions already have a number of attributes, some of which are
|
||||
writable, e.g. func_doc, a.k.a. func.__doc__. func_doc has the
|
||||
interesting property that there is special syntax in function (and
|
||||
method) definitions for implicitly setting the attribute. This
|
||||
convenience has been exploited over and over again, overloading
|
||||
docstrings with additional semantics.
|
||||
|
||||
For example, John Aycock has written a system where docstrings are
|
||||
used to define parsing rules[1]. Zope's ZPublisher ORB[2] uses
|
||||
|
@ -48,13 +48,12 @@ Proposal
|
|||
func_dict (a.k.a. __dict__). This dictionary can be set and get
|
||||
using ordinary attribute set and get syntax.
|
||||
|
||||
Unbound methods also gain set and get attribute syntax, but they
|
||||
modify the dictionary of the underlying function object. When
|
||||
accessed through bound methods, attributes can only be gotten;
|
||||
attempting to set an attribute on a bound method raises TypeError.
|
||||
This is because while function attributes appear to be unique to
|
||||
the bound method, they are really shared by all bound methods, via
|
||||
the underlying function object.
|
||||
Methods also gain `getter' syntax, and they currently access the
|
||||
attribute through the dictionary of the underlying function
|
||||
object. It is not possible to set attributes on bound or unbound
|
||||
methods, except by doing so explicitly on the underlying function
|
||||
object. See the `Future Directions' discussion below for
|
||||
approaches in subsequent versions of Python.
|
||||
|
||||
A function object's __dict__ can also be set, but only to a
|
||||
dictionary object (i.e. setting __dict__ to UserDict raises a
|
||||
|
@ -96,6 +95,60 @@ Other Uses
|
|||
|
||||
Future Directions
|
||||
|
||||
- A previous version of this PEP (and the accompanying
|
||||
implementation) allowed for both setter and getter of attributes
|
||||
on unbound methods, and only getter on bound methods. A number
|
||||
of problems were discovered with this policy.
|
||||
|
||||
Because method attributes were stored in the underlying
|
||||
function, this caused several potentially surprising results:
|
||||
|
||||
class C:
|
||||
def a(self): pass
|
||||
|
||||
c1 = C()
|
||||
c2 = C()
|
||||
c1.a.publish = 1
|
||||
# c2.a.publish would now be == 1 also!
|
||||
|
||||
Because a change to `a' bound c1 also caused a change to `a'
|
||||
bound to c2, setting of attributes on bound methods was
|
||||
disallowed. However, even allowing setting of attributes on
|
||||
unbound methods has its ambiguities:
|
||||
|
||||
class D(C): pass
|
||||
class E(C): pass
|
||||
|
||||
D.a.publish = 1
|
||||
# E.a.publish would now be == 1 also!
|
||||
|
||||
For this reason, the current PEP disallows setting attributes on
|
||||
either bound or unbound methods, but does allow for getting
|
||||
attributes on either -- both return the attribute value on the
|
||||
underlying function object.
|
||||
|
||||
The proposal for Python 2.2 is to implement setting (bound or
|
||||
unbound) method attributes by setting attributes on the instance
|
||||
or class, using special naming conventions. I.e.
|
||||
|
||||
class C:
|
||||
def a(self): pass
|
||||
|
||||
C.a.publish = 1
|
||||
C.__a_publish__ == 1 # true
|
||||
|
||||
c = C()
|
||||
c.a.publish = 2
|
||||
c.__a_publish__ == 2 # true
|
||||
|
||||
d = C()
|
||||
d.__a_publish__ == 1 # true
|
||||
|
||||
Here, a lookup on the instance would look to the instance's
|
||||
dictionary first, followed by a lookup on the class's
|
||||
dictionary, and finally a lookup on the function object's
|
||||
dictionary.
|
||||
|
||||
- Currently, Python supports function attributes only on Python
|
||||
functions (i.e. those that are written in Python, not those that
|
||||
are built-in). Should it be worthwhile, a separate patch can be
|
||||
|
|
Loading…
Reference in New Issue