added PEP 3130, Access to Current Module/Class/Function, by Jim J. Jewett
This commit is contained in:
parent
7ba16b49e0
commit
7ef3df6097
18
pep-0000.txt
18
pep-0000.txt
|
@ -78,7 +78,7 @@ Index by Category
|
|||
Accepted PEPs (accepted; may not be implemented yet)
|
||||
|
||||
SA 358 The "bytes" Object Schemenauer, GvR
|
||||
SA 3106 Revamping dict.keys(), .values() and .items() GvR
|
||||
SA 3106 Revamping dict.keys(), .values() & .items() GvR
|
||||
SA 3109 Raising Exceptions in Python 3000 Winter
|
||||
SA 3110 Catching Exceptions in Python 3000 Winter
|
||||
SA 3111 Simple input built-in in Python 3000 Roberge
|
||||
|
@ -128,6 +128,7 @@ Index by Category
|
|||
S 3127 Integer Literal Support and Syntax Maupin
|
||||
S 3128 BList: A Faster List-like Type Stutzbach
|
||||
S 3129 Class Decorators Winter
|
||||
S 3130 Access to Current Module/Class/Function Jewett
|
||||
S 3141 A Type Hierarchy for Numbers Yasskin
|
||||
|
||||
Finished PEPs (done, implemented in Subversion)
|
||||
|
@ -193,7 +194,7 @@ Index by Category
|
|||
SF 3104 Access to Names in Outer Scopes Yee
|
||||
SF 3105 Make print a function Brandl
|
||||
SF 3107 Function Annotations Winter, Lownds
|
||||
SF 3114 Renaming iterator.next() to iterator.__next__() Yee
|
||||
SF 3114 Renaming iterator.next() to .__next__() Yee
|
||||
|
||||
Empty PEPs (or containing only an abstract)
|
||||
|
||||
|
@ -234,7 +235,7 @@ Index by Category
|
|||
SW 274 Dict Comprehensions Warsaw
|
||||
SR 275 Switching on Multiple Values Lemburg
|
||||
SR 276 Simple Iterator for ints Althoff
|
||||
SR 281 Loop Counter Iteration with range and xrange Hetland
|
||||
SR 281 Loop Counter Iteration with range & xrange Hetland
|
||||
SR 284 Integer for-loops Eppstein, Ewing
|
||||
SW 288 Generators Attributes and Exceptions Hettinger
|
||||
SR 294 Type Names in the types Module Tirosh
|
||||
|
@ -254,7 +255,7 @@ Index by Category
|
|||
SW 321 Date/Time Parsing and Formatting Kuchling
|
||||
SR 325 Resource-Release Support for Generators Pedroni
|
||||
SR 326 A Case for Top and Bottom Values Carlson, Reedy
|
||||
SR 329 Treating Builtins as Constants in the Standard Library Hettinger
|
||||
SR 329 Treating Builtins as Constants in the StdLib Hettinger
|
||||
SR 330 Python Bytecode Verification Pelletier
|
||||
SR 332 Byte vectors and String/Unicode Unification Montanaro
|
||||
SW 334 Simple Coroutines via SuspendIteration Evans
|
||||
|
@ -377,7 +378,7 @@ Numerical Index
|
|||
SF 278 Universal Newline Support Jansen
|
||||
SF 279 The enumerate() built-in function Hettinger
|
||||
S 280 Optimizing access to globals GvR
|
||||
SR 281 Loop Counter Iteration with range and xrange Hetland
|
||||
SR 281 Loop Counter Iteration with range & xrange Hetland
|
||||
SF 282 A Logging System Sajip, Mick
|
||||
IF 283 Python 2.3 Release Schedule GvR
|
||||
SR 284 Integer for-loops Eppstein, Ewing
|
||||
|
@ -424,7 +425,7 @@ Numerical Index
|
|||
SR 326 A Case for Top and Bottom Values Carlson, Reedy
|
||||
SF 327 Decimal Data Type Batista
|
||||
SF 328 Imports: Multi-Line and Absolute/Relative Aahz
|
||||
SR 329 Treating Builtins as Constants in the Standard Library Hettinger
|
||||
SR 329 Treating Builtins as Constants in the StdLib Hettinger
|
||||
SR 330 Python Bytecode Verification Pelletier
|
||||
S 331 Locale-Independent Float/String Conversions Reis
|
||||
SR 332 Byte vectors and String/Unicode Unification Montanaro
|
||||
|
@ -474,7 +475,7 @@ Numerical Index
|
|||
SR 3103 A Switch/Case Statement GvR
|
||||
SF 3104 Access to Names in Outer Scopes Yee
|
||||
SF 3105 Make print a function Brandl
|
||||
SA 3106 Revamping dict.keys(), .values() and .items() GvR
|
||||
SA 3106 Revamping dict.keys(), .values() & .items() GvR
|
||||
SF 3107 Function Annotations Winter, Lownds
|
||||
S 3108 Standard Library Reorganization Cannon
|
||||
SA 3109 Raising Exceptions in Python 3000 Winter
|
||||
|
@ -482,7 +483,7 @@ Numerical Index
|
|||
SA 3111 Simple input built-in in Python 3000 Roberge
|
||||
SA 3112 Bytes literals in Python 3000 Orendorff
|
||||
SA 3113 Removal of Tuple Parameter Unpacking Cannon
|
||||
SF 3114 Renaming iterator.next() to iterator.__next__() Yee
|
||||
SF 3114 Renaming iterator.next() to .__next__() Yee
|
||||
SA 3115 Metaclasses in Python 3000 Talin
|
||||
S 3116 New I/O Stutzbach, Verdone, GvR
|
||||
S 3117 Postfix Type Declarations Brandl
|
||||
|
@ -498,6 +499,7 @@ Numerical Index
|
|||
S 3127 Integer Literal Support and Syntax Maupin
|
||||
S 3128 BList: A Faster List-like Type Stutzbach
|
||||
S 3129 Class Decorators Winter
|
||||
S 3130 Access to Current Module/Class/Function Jewett
|
||||
S 3141 A Type Hierarchy for Numbers Yasskin
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,206 @@
|
|||
PEP: 3130
|
||||
Title: Access to Current Module/Class/Function
|
||||
Version: $Revision$
|
||||
Last-Modified: $Date$
|
||||
Author: Jim J. Jewett <jimjjewett@gmail.com>
|
||||
Status: Draft
|
||||
Type: Standards Track
|
||||
Content-Type: text/plain
|
||||
Created: 22-Apr-2007
|
||||
Python-Version: 3.0
|
||||
Post-History: 22-Apr-2007
|
||||
|
||||
|
||||
Abstract
|
||||
|
||||
It is common to need a reference to the current module, class,
|
||||
or function, but there is currently no entirely correct way to
|
||||
do this. This PEP proposes adding the keywords __module__,
|
||||
__class__, and __function__.
|
||||
|
||||
|
||||
Rationale for __module__
|
||||
|
||||
Many modules export various functions, classes, and other objects,
|
||||
but will perform additional activities (such as running unit
|
||||
tests) when run as a script. The current idiom is to test whether
|
||||
the module's name has been set to magic value.
|
||||
|
||||
if __name__ == "__main__": ...
|
||||
|
||||
More complicated introspection requires a module to (attempt to)
|
||||
import itself. If importing the expected name actually produces
|
||||
a different module, there is no good workaround.
|
||||
|
||||
# __import__ lets you use a variable, but... it gets more
|
||||
# complicated if the module is in a package.
|
||||
__import__(__name__)
|
||||
|
||||
# So just go to sys modules... and hope that the module wasn't
|
||||
# hidden/removed (perhaps for security), that __name__ wasn't
|
||||
# changed, and definitely hope that no other module with the
|
||||
# same name is now available.
|
||||
class X(object):
|
||||
pass
|
||||
|
||||
import sys
|
||||
mod = sys.modules[__name__]
|
||||
mod = sys.modules[X.__class__.__module__]
|
||||
|
||||
Proposal: Add a __module__ keyword which refers to the module
|
||||
currently being defined (executed). (But see open issues.)
|
||||
|
||||
# XXX sys.main is still changing as draft progresses. May
|
||||
# really need sys.modules[sys.main]
|
||||
if __module__ is sys.main: # assumes PEP (3122), Cannon
|
||||
...
|
||||
|
||||
|
||||
Rationale for __class__
|
||||
|
||||
Class methods are passed the current instance; from this they can
|
||||
determine self.__class__ (or cls, for class methods).
|
||||
Unfortunately, this reference is to the object's actual class,
|
||||
which may be a subclass of the defining class. The current
|
||||
workaround is to repeat the name of the class, and assume that the
|
||||
name will not be rebound.
|
||||
|
||||
class C(B):
|
||||
|
||||
def meth(self):
|
||||
super(C, self).meth() # Hope C is never rebound.
|
||||
|
||||
class D(C):
|
||||
|
||||
def meth(self):
|
||||
# ?!? issubclass(D,C), so it "works":
|
||||
super(C, self).meth()
|
||||
|
||||
Proposal: Add a __class__ keyword which refers to the class
|
||||
currently being defined (executed). (But see open issues.)
|
||||
|
||||
class C(B):
|
||||
def meth(self):
|
||||
super(__class__, self).meth()
|
||||
|
||||
Note that super calls may be further simplified by the "New Super"
|
||||
PEP (Spealman). The __class__ (or __this_class__) attribute came
|
||||
up in attempts to simplify the explanation and/or implementation
|
||||
of that PEP, but was separated out as an independent decision.
|
||||
|
||||
Note that __class__ (or __this_class__) is not quite the same as
|
||||
the __thisclass__ property on bound super objects. The existing
|
||||
super.__thisclass__ property refers to the class from which the
|
||||
Method Resolution Order search begins. In the above class D, it
|
||||
would refer to (the current reference of name) C.
|
||||
|
||||
|
||||
Rationale for __function__
|
||||
|
||||
Functions (including methods) often want access to themselves,
|
||||
usually for a private storage location or true recursion. While
|
||||
there are several workarounds, all have their drawbacks.
|
||||
|
||||
def counter(_total=[0]):
|
||||
# _total shouldn't really appear in the
|
||||
# signature at all; the list wrapping and
|
||||
# [0] unwrapping obscure the code
|
||||
_total[0] += 1
|
||||
return _total[0]
|
||||
|
||||
@annotate(total=0)
|
||||
def counter():
|
||||
# Assume name counter is never rebound:
|
||||
counter.total += 1
|
||||
return counter.total
|
||||
|
||||
# class exists only to provide storage:
|
||||
class _wrap(object):
|
||||
|
||||
__total = 0
|
||||
|
||||
def f(self):
|
||||
self.__total += 1
|
||||
return self.__total
|
||||
|
||||
# set module attribute to a bound method:
|
||||
accum = _wrap().f
|
||||
|
||||
# This function calls "factorial", which should be itself --
|
||||
# but the same programming styles that use heavy recursion
|
||||
# often have a greater willingness to rebind function names.
|
||||
def factorial(n):
|
||||
return (n * factorial(n-1) if n else 1)
|
||||
|
||||
Proposal: Add a __function__ keyword which refers to the function
|
||||
(or method) currently being defined (executed). (But see open
|
||||
issues.)
|
||||
|
||||
@annotate(total=0)
|
||||
def counter():
|
||||
# Always refers to this function obj:
|
||||
__function__.total += 1
|
||||
return __function__.total
|
||||
|
||||
def factorial(n):
|
||||
return (n * __function__(n-1) if n else 1)
|
||||
|
||||
|
||||
Backwards Compatibility
|
||||
|
||||
While a user could be using these names already, double-underscore
|
||||
names ( __anything__ ) are explicitly reserved to the interpreter.
|
||||
It is therefore acceptable to introduce special meaning to these
|
||||
names within a single feature release.
|
||||
|
||||
|
||||
Implementation
|
||||
|
||||
Ideally, these names would be keywords treated specially by the
|
||||
bytecode compiler.
|
||||
|
||||
Guido has suggested [1] using a cell variable filled in by the
|
||||
metaclass.
|
||||
|
||||
Michele Simionato has provided a prototype using bytecode hacks
|
||||
[2]. This does not require any new bytecode operators; it just
|
||||
modifies the which specific sequence of existing operators gets
|
||||
run.
|
||||
|
||||
|
||||
Open Issues
|
||||
|
||||
- Are __module__, __class__, and __function__ the right names? In
|
||||
particular, should the names include the word "this", either as
|
||||
__this_module__, __this_class__, and __this_function__, (format
|
||||
discussed on the python-3000 and python-ideas lists) or as
|
||||
__thismodule__, __thisclass__, and __thisfunction__ (inspired
|
||||
by, but conflicting with, current usage of super.__thisclass__).
|
||||
|
||||
- Are all three keywords needed, or should this enhancement be
|
||||
limited to a subset of the objects? Should methods be treated
|
||||
separately from other functions?
|
||||
|
||||
|
||||
References
|
||||
|
||||
[1] Fixing super anyone? Guido van Rossum
|
||||
http://mail.python.org/pipermail/python-3000/2007-April/006671.html
|
||||
|
||||
[2] Descriptor/Decorator challenge, Michele Simionato
|
||||
http://groups.google.com/group/comp.lang.python/browse_frm/thread/a6010c7494871bb1/62a2da68961caeb6?lnk=gst&q=simionato+challenge&rnum=1&hl=en#62a2da68961caeb6
|
||||
|
||||
|
||||
Copyright
|
||||
|
||||
This document has been placed in the public domain.
|
||||
|
||||
|
||||
|
||||
Local Variables:
|
||||
mode: indented-text
|
||||
indent-tabs-mode: nil
|
||||
sentence-end-double-space: t
|
||||
fill-column: 70
|
||||
coding: utf-8
|
||||
End:
|
Loading…
Reference in New Issue