2

Peter Norvig によるコードの「さらに優れた Python Lisp インタープリター」のポイントを理解するのに苦労しています

解析を目的とした eval 関数で、彼はテスト isanstance(x,Symbol) を行っています。クラス Symbol は前に定義されていますが、pass で宣言されているため、メソッドはありません。

 class Symbol(str): pass

これらの行は、symbol_table を構築します。

def Sym(s, symbol_table={}):
    "Find or create unique Symbol entry for str s in symbol table."
    if s not in symbol_table: symbol_table[s] = Symbol(s)
    return symbol_table[s]

_quote, _if, _set, _define, _lambda, _begin, _definemacro, = map(Sym, 
"quote   if   set!  define   lambda   begin   define-macro".split())

_quasiquote, _unquote, _unquotesplicing = map(Sym,
"quasiquote   unquote   unquote-splicing".split())

Symbol(s)Symbol クラスのコンストラクターが定義されていないため、なぜ機能するのかわかりません。その後、evalメソッドはトークンが Symbol かどうかを次のようにチェックします。

def eval(x, env=global_env):
     "Evaluate an expression in an environment."
      while True:
          if isa(x, Symbol):       # variable reference
              return env.find(x)[x]
          else: #other stuff

isa(x,Symbol)謎です。ここのコードでは、token が変数参照 (つまり、以前に定義された x を持つ x) であるかどうかを確認する必要があります。私の意見では、ここのシンボルは文字列の装飾であり、で構築された初期化リストにあります

  _quote, _if, _set, _define, _lambda, _begin, _definemacro, = map(Sym, 
     "quote   if   set!  define   lambda   begin   define-macro".split())

P. Norvig によるこのコードの知識や読み方、または Python の経験に基づいて説明していただけますか? ありがとう

4

2 に答える 2

4

他のすべてのメソッドと同様に、__init__継承されます。のSymbolを継承します。str__init__

更新:さらに、__init__構築ではなく初期化を実行することに注意してください。初期化コード (わずかに異なる効果を持つ) もクラス定義内に存在する可能性があります。これは、有効なオブジェクトが__init__呼び出されなくても存在できることを意味します。

于 2012-07-19T13:04:40.457 に答える
2

Symbol のクラス定義は、それが のサブクラスであることだけですstr。つまり、ほとんどの意図と目的のための文字列です。

>>> class Symbol(str): pass
... 
>>> x=Symbol('abc')
>>> x
'abc'

ただし、これは新しいクラスです。つまり、インタープリターによって少し異なる方法で処理されます。

>>> x == 'abc' # __eq__ is inherited
True
>>> x is 'abc' # different memory location from 'abc'
False
>>> y='abc'
>>> y is 'abc'
True

isaは (むしろ不必要な) の再定義でありisinstance、変数が のインスタンスであるかどうかをチェックするだけですSymbol:

>>> isa = isinstance
>>> isa('abc', Symbol)
False
>>> isa(x, Symbol)
True
于 2012-07-19T12:59:40.480 に答える