Clarify rules for names defined in class scope. (Classes hide names
was a bad label.) Add note about how to implement flat closures using an extra level of indirection.
This commit is contained in:
parent
0bb1267cae
commit
4be092d93e
52
pep-0227.txt
52
pep-0227.txt
|
@ -56,11 +56,9 @@ Specification
|
||||||
|
|
||||||
If a name is used within a code block, but it is not bound there
|
If a name is used within a code block, but it is not bound there
|
||||||
and is not declared global, the use is treated as a reference to
|
and is not declared global, the use is treated as a reference to
|
||||||
the nearest enclosing function region. A region is visible from a
|
the nearest enclosing function region. (Note: If a region is
|
||||||
block is all enclosing blocks are introduced by function
|
contained within a class definition, the name bindings that occur
|
||||||
defintions. (Note: If a region is contained within a class
|
in the class block are not visible to enclosed functions.)
|
||||||
definition, the name bindings that occur in the class block are
|
|
||||||
not visible to enclosed functions.)
|
|
||||||
|
|
||||||
A class definition is an executable statement that may uses and
|
A class definition is an executable statement that may uses and
|
||||||
definitions of names. These references follow the normal rules
|
definitions of names. These references follow the normal rules
|
||||||
|
@ -111,19 +109,19 @@ Discussion
|
||||||
name resolution rules are typical for statically scoped languages,
|
name resolution rules are typical for statically scoped languages,
|
||||||
with three primary exceptions:
|
with three primary exceptions:
|
||||||
|
|
||||||
- Class definitions hide names.
|
- Names in class scope are not accessible.
|
||||||
- The global statement short-circuits the normal rules.
|
- The global statement short-circuits the normal rules.
|
||||||
- Variables are not declared.
|
- Variables are not declared.
|
||||||
|
|
||||||
Class definitions hide names. Names are resolved in the innermost
|
Names in class scope are not accessible. Names are resolved in
|
||||||
enclosing function scope. If a class defintion occurs in a chain
|
the innermost enclosing function scope. If a class defintion
|
||||||
of nested scopes, the resolution process skips class definitions.
|
occurs in a chain of nested scopes, the resolution process skips
|
||||||
This rule prevents odd interactions between class attributes and
|
class definitions. This rule prevents odd interactions between
|
||||||
local variable access. If a name binding operation occurs in a
|
class attributes and local variable access. If a name binding
|
||||||
class defintion, it creates an attribute on the resulting class
|
operation occurs in a class defintion, it creates an attribute on
|
||||||
object. To access this variable in a method, or in a function
|
the resulting class object. To access this variable in a method,
|
||||||
nested within a method, an attribute reference must be used,
|
or in a function nested within a method, an attribute reference
|
||||||
either via self or via the class name.
|
must be used, either via self or via the class name.
|
||||||
|
|
||||||
An alternative would have been to allow name binding in class
|
An alternative would have been to allow name binding in class
|
||||||
scope to behave exactly like name binding in function scope. This
|
scope to behave exactly like name binding in function scope. This
|
||||||
|
@ -295,17 +293,17 @@ Implementation
|
||||||
code and the environment in which to resolve free variables.
|
code and the environment in which to resolve free variables.
|
||||||
|
|
||||||
There are a variety of implementation alternatives for closures.
|
There are a variety of implementation alternatives for closures.
|
||||||
One possibility is to use a static link from a nested function to
|
Two typical ones are nested closures and flat closures. Nested
|
||||||
its enclosing environment. This implementation requires several
|
closures use a static link from a nested function to its enclosing
|
||||||
links to be followed if there is more than one level of nesting
|
environment. This implementation requires several links to be
|
||||||
and keeps many garbage objects alive longer than necessary.
|
followed if there is more than one level of nesting and keeps many
|
||||||
|
garbage objects alive longer than necessary.
|
||||||
|
|
||||||
One fairly simple implementation approach would be to implement
|
Flat closures are roughly similar to the default argument hack
|
||||||
the default argument hack currently used for lambda support. Each
|
currently used for lambda support. Each function object would
|
||||||
function object would have a func_env slot that holds a tuple of
|
have a func_env slot that holds a tuple of free variable bindings.
|
||||||
free variable bindings. The code inside the function would use
|
The code inside the function would use LOAD_ENV to access these
|
||||||
LOAD_ENV to access these bindings rather than the typical
|
bindings rather than the typical LOAD_FAST.
|
||||||
LOAD_FAST.
|
|
||||||
|
|
||||||
The problem with this approach is that rebindings are not visible
|
The problem with this approach is that rebindings are not visible
|
||||||
to the nested function. Consider the following example:
|
to the nested function. Consider the following example:
|
||||||
|
@ -329,6 +327,10 @@ Implementation
|
||||||
definition time. This is the default argument hack, but not
|
definition time. This is the default argument hack, but not
|
||||||
actual name resolution based on statically nested scopes.
|
actual name resolution based on statically nested scopes.
|
||||||
|
|
||||||
|
To support shared visibility of updates, it will be necessary to
|
||||||
|
have a tuple of cells that contain references to variables. The
|
||||||
|
extra level of indirection should allow updates to be shared.
|
||||||
|
|
||||||
It is not clear whether the current 1-pass Python compiler can
|
It is not clear whether the current 1-pass Python compiler can
|
||||||
determine which references are to globals and which are references
|
determine which references are to globals and which are references
|
||||||
to enclosing scopes. It may be possible to make minimal changes
|
to enclosing scopes. It may be possible to make minimal changes
|
||||||
|
|
Loading…
Reference in New Issue