lambda、可调用类实例和作用域;为什么';它在Python2.7中不起作用吗?
有人能给我解释一下为什么下面的代码会产生异常吗lambda、可调用类实例和作用域;为什么';它在Python2.7中不起作用吗?,python,lambda,python-2.7,scope,Python,Lambda,Python 2.7,Scope,有人能给我解释一下为什么下面的代码会产生异常吗 >>> class CallableKlass(object): def __init__(self, callible): self.callible = callible def __call__(self, arg): return self.callible(arg) >>> class Klass(object): d = {'foo': 'b
>>> class CallableKlass(object):
def __init__(self, callible):
self.callible = callible
def __call__(self, arg):
return self.callible(arg)
>>> class Klass(object):
d = {'foo': 'bar'}
m = CallableKlass(lambda x: d[x])
>>> Klass.m('foo')
Traceback (most recent call last):
File "<pyshell#10>", line 1, in <module>
Klass.m('foo')
File "<pyshell#5>", line 5, in __call__
return self.callible(arg)
File "<pyshell#9>", line 3, in <lambda>
m = CallableKlass(lambda x: d[x])
NameError: global name 'd' is not defined
类CallableKlass(对象):
定义初始化(自,可调用):
self.callable=callable
定义调用(self,arg):
返回自调用(arg)
>>>类Klass(对象):
d={'foo':'bar'}
m=可调用Klass(λx:d[x])
>>>Klass.m(‘foo’)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
Klass.m(‘foo’)
文件“”,第5行,在调用中__
返回自调用(arg)
文件“”,第3行,在
m=可调用Klass(λx:d[x])
NameError:未定义全局名称“d”
您应该在lambda中使用
Klass.d
,因为在类中声明的变量成为该类的属性。
这就是为什么您的程序会引发该错误,因为它无法在全局变量中找到类似d
的内容:
class Klass(object):
d = {'foo': 'bar'}
m = CallableKlass(lambda x: Klass.d[x])
类命名空间(直接在类主体中定义的内容)无法从该命名空间中定义的函数中访问。lambda只是一个函数,因此这也适用于lambda。你的CallableKlass
是一条红鲱鱼。在这种更简单的情况下,行为是相同的:
>>> class Foo(object):
... d = {'foo': 'bar'}
... (lambda stuff: d[stuff])('foo')
Traceback (most recent call last):
File "<pyshell#3>", line 1, in <module>
class Foo(object):
File "<pyshell#3>", line 3, in Foo
(lambda stuff: d[stuff])('foo')
File "<pyshell#3>", line 3, in <lambda>
(lambda stuff: d[stuff])('foo')
NameError: global name 'd' is not defined
>>> class Foo(object):
... d = {'foo': 'bar'}
... def f(stuff):
... d[stuff]
... f('foo')
Traceback (most recent call last):
File "<pyshell#4>", line 1, in <module>
class Foo(object):
File "<pyshell#4>", line 5, in Foo
f('foo')
File "<pyshell#4>", line 4, in f
d[stuff]
NameError: global name 'd' is not defined
>>类Foo(对象):
... d={'foo':'bar'}
... (lambda stuff:d[stuff])('foo')
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
类Foo(对象):
文件“”,第3行,在Foo中
(lambda stuff:d[stuff])('foo')
文件“”,第3行,在
(lambda stuff:d[stuff])('foo')
NameError:未定义全局名称“d”
>>>类Foo(对象):
... d={'foo':'bar'}
... def f(材料):
... d[材料]
... f(‘foo’)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
类Foo(对象):
文件“”,第5行,在Foo中
f(‘foo’)
文件“”,第4行,在f中
d[材料]
NameError:未定义全局名称“d”
我认为这是类
而不是Klass
@iTayb我认为OP只是想避免关键字冲突。+1。你知道Python为什么选择展示这种行为吗?它似乎与它的正常闭包规则不一致——在中定义的cf函数functions@poorsod:我不完全确定,但我认为这是为了避免方法名隐藏全局函数。如果类级属性在后续方法的范围内,并且您编写了一个包含sum
方法的类,那么类块中在该类之后定义的所有方法将不再能够访问内置的sum
函数(它们将改为读取刚刚定义的方法)。