Python 2.x嵌套作用域的限制
2016-10-16 01:42
225 查看
python是一门静态作用域的语言,PEP 227在python 2.1开始引入了一项语言新特性——静态嵌套作用域。
当然,新特性也伴随而来了一些新问题。在函数作用域内执行
比如下面
这种情况下有两种策略:
编译时放任不管,运行时再根据实际情况绑定
这会导致人在看代码的时候,也无法确定
编译时直接强行静态绑定,忽略动态语句可能的影响
如果动态语句真的在当前作用域中创建了新的名称绑定,那这些名称就对当前作用域中的嵌套作用域不可见了,这违背了PEP 227本身的设计目标
两种策略各有弊病,所以PEP 227最终决定:
根据这个异常提示信息,也可以反过来总结出抛异常的两个条件:
嵌套函数内部引用了自由变量,也就是外部名称
要解决这个问题,只需使用
其实这种方法跟上面说的第二种策略是一个意思,只不过把控制权从编译器交给了开发者。
python 3中对
详情参见PEP 227 – Statically Nested Scopes
当然,新特性也伴随而来了一些新问题。在函数作用域内执行
bare exec或
import *的时候,可能会在local namespace中创建新的名称。但由于是动态语句,python在编译时无法确定是否真的会创建新名称,所以也就无法在编译时确定嵌套函数中的名称绑定。
比如下面
inner函数中的名称
x,编译时无法确定是否应该绑定到global namespace的名称
x,因为
exec str可能会在local namespace中也创建名称
x:
x = 1 def outer(str): exec str # str = 'x=2' def inner(): print x
这种情况下有两种策略:
编译时放任不管,运行时再根据实际情况绑定
这会导致人在看代码的时候,也无法确定
inner函数内的名称
x到底如何绑定,同时也违背了python的静态作用域设计目标
编译时直接强行静态绑定,忽略动态语句可能的影响
如果动态语句真的在当前作用域中创建了新的名称绑定,那这些名称就对当前作用域中的嵌套作用域不可见了,这违背了PEP 227本身的设计目标
两种策略各有弊病,所以PEP 227最终决定:
SyntaxError: unqualified exec is not allowed in function 'xxxx' because it contains a nested function with free variables
根据这个异常提示信息,也可以反过来总结出抛异常的两个条件:
bare exec(unqualified exec),或者
import *
嵌套函数内部引用了自由变量,也就是外部名称
要解决这个问题,只需使用
exec ... in ...语句就可以了。这样
exec语句就能保证不会对local namespace产生任何影响(修改
locals()不会真的影响局部变量),编译器就能放心的忽略
exec语句的影响而直接静态绑定了。这也是为什么
exec需要是个关键字而不是库函数。
其实这种方法跟上面说的第二种策略是一个意思,只不过把控制权从编译器交给了开发者。
python 3中对
exec语义做了一些修改,就不存在这个问题了,所以它不需要再是关键字,变成了一个函数。
详情参见PEP 227 – Statically Nested Scopes
相关文章推荐
- 关于"Google限制Python"事件我的看法
- 使用 python 破除网页限制
- python变量作用域
- Python变量作用域与Pyunit
- 分享:python,限制任意函数,线程的执行时间或根据条件终止.
- python变量作用域
- python 变量作用域
- PHP成员变量作用域的限制-private
- python 变量作用域
- python 破除网页限制的基本方法
- Google将限制Python语言的应用 开发社区热议
- 用Python 实现刷钻网上抢任务,并实现一个简单的限制使用时间的功能
- python 变量作用域
- [Dynamic Language] Python __slots__ 限制绑定属性
- JSTL 入门;限制了作用域的变量
- 用python搜google,突破网页限制(forbidden)
- Google将限制Python语言的应用?
- 关于python的变量作用域
- python语法31[变量的作用域+global]
- Python 函数和作用域