简体   繁体   English

Python嵌套类混淆

[英]Python nested class confusion

I am studying the idea about lazy evaluation. 我正在研究关于惰性评估的想法。 This is the Stream class I am having trouble with: refer to 4.2.6 Stream 这是我遇到麻烦的Stream类: 请参阅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))

Then I create a toy Stream for testing: 然后,我创建一个玩具Stream进行测试:

s = Stream(1, lambda: Stream(2+3, lambda: Stream(9)))

I want to know what will happen when I reach the end of Stream , so I do: 我想知道到达Stream结束时会发生什么,所以我这样做:

s.rest.rest.rest

What I expect is the screen to print out Stream.empty since the last element is lambda: empty , but I got error traceback message: 我期望的是屏幕可以打印出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

So my question is, I do have my empty defined as a class variable, but the interpreter says it is not defined. 所以我的问题是,我确实将我的empty定义为类变量,但是解释器说它没有定义。 If I take the Empty class definition out of nested class to the global frame, the code works. 如果我将Empty类定义从嵌套类中移到全局框架中,则代码将起作用。

Do I understand how nested class work wrong? 我是否了解嵌套类的工作方式有误? Anyone please give me a hint. 有人请给我一个提示。 Thanks for your time. 谢谢你的时间。

The code in that post is invalid and broken. 该帖子中的代码无效且已损坏。 The lambda will look up the name empty in a parent scope. lambda将在父作用域中查找empty名称。 The problem here then is that a class body is not a scope nestable scope , so only the global scope remains for the lookup. 那么这里的问题是,类主体不是作用域可嵌套的作用域 ,因此仅全局作用域保留用于查找。

From the 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 它不会扩展到方法的代码块

It doesn't matter here that the lambda is not a method but a callable bound as a default value for an argument for a method. 在这里, lambda不是方法,而是可调用绑定作为方法参数的默认值并不重要。

You can reference it using the class name instead: 您可以使用类名来引用它:

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

because Stream is now a global (set by running the class statement). 因为Stream现在是全局的(通过运行class语句设置)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM