Python 嵌套 class 混乱
Python nested class confusion
正在研究惰性求值的思想。这是 Stream
class 我遇到的问题:refer to 4.2.6 Stream
class Stream:
"""A lazily computed linked list."""
class Empty:
def __repr__(self):
return 'Stream.empty'
empty = Empty()
def __init__(self, first, compute_rest= lambda: empty):
assert callable(compute_rest), 'compute_rest must be callable.'
self.first = first
self._compute_rest = compute_rest
@property
def rest(self):
"""Return the rest of the stream, computing it if necessary."""
if self._compute_rest is not None:
self._rest = self._compute_rest()
self._compute_rest = None
return self._rest
def __repr__(self):
return 'Stream({0}, <...>)'.format(repr(self.first))
然后我制作了一个玩具Stream
用于测试:
s = Stream(1, lambda: Stream(2+3, lambda: Stream(9)))
我想知道当我到达 Stream
结尾时会发生什么,所以我这样做:
s.rest.rest.rest
我期望屏幕打印出 Stream.empty
,因为最后一个元素是 lambda: empty
,但我收到错误回溯消息:
NameError Traceback (most recent call last)
<ipython-input-6-64cf45661094> in <module>()
----> 1 s.rest.rest.rest
<ipython-input-4-7cc49730db55> in rest(self)
16 """Return the rest of the stream, computing it if necessary."""
17 if self._compute_rest is not None:
---> 18 self._rest = self._compute_rest()
19 self._compute_rest = None
20 return self._rest
<ipython-input-4-7cc49730db55> in <lambda>()
7 empty = Empty()
8
----> 9 def __init__(self, first, compute_rest= lambda: empty):
10 assert callable(compute_rest), 'compute_rest must be callable.'
11 self.first = first
NameError: name 'empty' is not defined
所以我的问题是,我确实将 empty
定义为 class 变量,但解释器说它没有定义。如果我将 Empty
class 定义从嵌套 class 中取出到全局框架,代码就可以工作。
我明白嵌套 class 是怎么出错的吗?
任何人都请给我一个提示。感谢您的宝贵时间。
post 中的代码无效且损坏。 lambda
将在父作用域中查找名称 empty
。这里的问题是 class 主体 不是可嵌套范围的范围 ,因此只有全局范围保留用于查找。
来自Execution Model documentation:
The scope of names defined in a class block is limited to the class block; it does not extend to the code blocks of methods
lambda
不是方法而是作为方法参数的默认值的可调用绑定在这里无关紧要。
您可以使用 class 名称来引用它:
def __init__(self, first, compute_rest= lambda: Stream.empty):
因为 Stream
现在是全局的(由 运行 和 class
语句设置)。
正在研究惰性求值的思想。这是 Stream
class 我遇到的问题:refer to 4.2.6 Stream
class Stream:
"""A lazily computed linked list."""
class Empty:
def __repr__(self):
return 'Stream.empty'
empty = Empty()
def __init__(self, first, compute_rest= lambda: empty):
assert callable(compute_rest), 'compute_rest must be callable.'
self.first = first
self._compute_rest = compute_rest
@property
def rest(self):
"""Return the rest of the stream, computing it if necessary."""
if self._compute_rest is not None:
self._rest = self._compute_rest()
self._compute_rest = None
return self._rest
def __repr__(self):
return 'Stream({0}, <...>)'.format(repr(self.first))
然后我制作了一个玩具Stream
用于测试:
s = Stream(1, lambda: Stream(2+3, lambda: Stream(9)))
我想知道当我到达 Stream
结尾时会发生什么,所以我这样做:
s.rest.rest.rest
我期望屏幕打印出 Stream.empty
,因为最后一个元素是 lambda: empty
,但我收到错误回溯消息:
NameError Traceback (most recent call last)
<ipython-input-6-64cf45661094> in <module>()
----> 1 s.rest.rest.rest
<ipython-input-4-7cc49730db55> in rest(self)
16 """Return the rest of the stream, computing it if necessary."""
17 if self._compute_rest is not None:
---> 18 self._rest = self._compute_rest()
19 self._compute_rest = None
20 return self._rest
<ipython-input-4-7cc49730db55> in <lambda>()
7 empty = Empty()
8
----> 9 def __init__(self, first, compute_rest= lambda: empty):
10 assert callable(compute_rest), 'compute_rest must be callable.'
11 self.first = first
NameError: name 'empty' is not defined
所以我的问题是,我确实将 empty
定义为 class 变量,但解释器说它没有定义。如果我将 Empty
class 定义从嵌套 class 中取出到全局框架,代码就可以工作。
我明白嵌套 class 是怎么出错的吗? 任何人都请给我一个提示。感谢您的宝贵时间。
post 中的代码无效且损坏。 lambda
将在父作用域中查找名称 empty
。这里的问题是 class 主体 不是可嵌套范围的范围 ,因此只有全局范围保留用于查找。
来自Execution Model documentation:
The scope of names defined in a class block is limited to the class block; it does not extend to the code blocks of methods
lambda
不是方法而是作为方法参数的默认值的可调用绑定在这里无关紧要。
您可以使用 class 名称来引用它:
def __init__(self, first, compute_rest= lambda: Stream.empty):
因为 Stream
现在是全局的(由 运行 和 class
语句设置)。