【问题标题】:Python nested class confusionPython嵌套类混淆
【发布时间】:2015-02-28 18:35:14
【问题描述】:

我正在研究关于惰性评估的想法。这是我遇到问题的 Stream 类: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 定义为类变量,但解释器说它没有定义。如果我将 Empty 类定义从嵌套类中取出到全局框架中,则代码可以工作。

我是否了解嵌套类的工作方式错误? 任何人请给我一个提示。感谢您的宝贵时间。

【问题讨论】:

  • “我确实将我的空定义为一个类变量”,但是你试图访问它一个普通变量,使用:Stream.empty
  • @AshwiniChaudhary 谢谢你,直截了当!

标签: python lambda stream nested-class


【解决方案1】:

该帖子中的代码无效且已损坏。 lambda 将在父作用域中查找名称 empty。那么这里的问题是类主体不是可嵌套的范围,因此只有全局范围可供查找。

来自Execution Model documentation

类块中定义的名称范围仅限于类块;它没有扩展到方法的代码块

lambda 不是方法,而是作为方法参数的默认值的可调用绑定,这并不重要。

您可以改用类名来引用它:

def __init__(self, first, compute_rest= lambda: Stream.empty):

因为Stream 现在是一个全局变量(通过运行class 语句设置)。

【讨论】:

  • 感谢您的参考链接。很有帮助。
猜你喜欢
  • 2015-09-21
  • 1970-01-01
  • 2021-03-11
  • 1970-01-01
  • 2014-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-11
相关资源
最近更新 更多