[fp] Python函数竟然不支持词法作用域

Lich_Ray 2007-06-09
今天突然发现的。狂晕。
症状1:
def up_level():
    var1 = 30
    def in_level ():
        return val1
    return in_level()

>>> up_level()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "<stdin>", line 5, in up_level
  File "<stdin>", line 4, in in_level
NameError: global name 'val1' is not defined
症状2:
用lambda也不行!
必须要在上层用locals()保存一下再传过去!
simohayha 2007-06-09
晕了,你的是var1和val1肯定会出错了.

PS:发觉我虽然近视,可是眼力还是不错.哈哈哈。
Lich_Ray 2007-06-09
好吧。算我这个例子举错了。不过Python真的有问题。
等会儿再讨论。
Lich_Ray 2007-06-09
好吧,来看看这个:
def up_level (val1):
	val2 = 12
	def in_level ():
		return (val1, val2)
	return in_level()

>>> up_level(100)
(100, 12)
但是:
def up_level (val1):
	val2 = 12
	def in_level ():
		val2 = val1 + val2
		return val2
	return in_level()

>>> up_level(100)

Traceback (most recent call last):
  File "<pyshell#14>", line 1, in -toplevel-
    up_level(100)
  File "<pyshell#13>", line 6, in up_level
    return in_level()
  File "<pyshell#13>", line 4, in in_level
    val2 = val1 + val2
UnboundLocalError: local variable 'val2' referenced before assignment

这样它又分不清楚了。如果它采用函数式的看法,至少应该创建新的局部变量 val2,采用命令式的看法,应该修改全局变量 val2。然而他什么也没做。如果在顶层还可以用 global 指定一下,现在怎么办?
PS: 我用的 python2.4。这至少是个bug,要不就是 Python 又开始耍“实用主义”的脾气,不允许诡异的用法。如果是前者我接受;如果是后者,直接将 Python 踢出“最喜爱的编程语言”列表。
simohayha 2007-06-09
你看python in nutshell里的这句
引用

Code in a nested function's body may access (but not rebind) local variables of an outer function, also known as free variables of the nested function.


你要改的话,直接再加一个变量不就行了.


simohayha 2007-06-09
看下这句,python in nutshell里的。
引用

Code in a nested function's body may access (but not rebind) local variables of an outer function, also known as free variables of the nested function.

这里你要修改的话,直接在内部添个local变量不就行了.

在这里我们无法重新绑定外部函数的变量,不过py3000就可以了。
py3000的话,看这里

http://wiki.woodpecker.org.cn/moin/Python3000


Lich_Ray 2007-06-09
nonlocal?——冷笑。
看来Python3000又加了不少东西啊。
PS: 那个"元数据"加的实在是……汗...
waterwalk 2007-06-11
Python中,对于非最内层变量都是“只读”的,一旦要赋值,实际就是重新定义了一个新的变量了。Python自带文档的Tutorial说得很清楚:

If a name is declared global, then all references and assignments go directly to the middle scope containing the module's global names. Otherwise, all variables found outside of the innermost scope are read-only (an attempt to write to such a variable will simply create a new local variable in the innermost scope, leaving the identically named outer variable unchanged).

...

A special quirk of Python is that assignments always go into the innermost scope.

Lich_Ray 2007-06-12
不过,看上面的例程可以知道,在同一个表达式中,Python 对二者分不清楚。
simohayha 2007-06-12
呵呵,越来越觉得,python对fp的支持,真的是很蹩脚地说.
Global site tag (gtag.js) - Google Analytics