Python 简介(7)

注意特定的异常 小心: 当key不存在时,dict[key]会抛出KeyError; lisp哈希表的用户则期望得到nil。你应该捕获这个异常或者用key in dict测试。

Python是Lisp-1的。 我的意思是Python只有一个命名空间,里面包含了变量和函数,就像scheme一样,而不是想Common Lisp那样,有两个命名空间。例如:

1

2

3

 

def f(list, len): return list((len, len(list)))      ## bad Python

(define (f list length) (list length (length list))) ;; bad Scheme

(defun f (list length) (list length (length list)))  ;; legal Common Lisp

 

对于域和方法也是一样:你不能提供一个和域名相同的方法名:

1

2

3

 

class C:

    def f(self): return self.f  ## bad Python

    ...

 

Python字符串不同于Lisp的符号(symbol)。Python通过把字符串内化到模块或类的哈希表中,然后进行符号查找。也就是说,当你写obj.slot时,Python在运行阶段会去obj类的哈希表中查找字符串"slot"。Python也会内化一些用户代码中的字符串,例如,当你写x = "str"时。但是Python并不内化那些看起来不像变量的字符串,例如x = "a str"(感谢Brian Spilsbur指出这点)。

Python没有宏(macro)。 Python可以访问一个程序的抽象语法树,但是这不是适合“心脏不好”的人。从积极的方面来看,该模块容易理解,并且在5分钟内,我用5行代码就可以得到:

1

2

3

4

5

 

>>> parse("2 + 2")

['eval_input', ['testlist', ['test', ['and_test', ['not_test', ['comparison',

 ['expr', ['xor_expr', ['and_expr', ['shift_expr', ['arith_expr', ['term', 

  ['factor', ['power', ['atom', [2, '2']]]]], [14, '+'], ['term', ['factor',

   ['power', ['atom', [2, '2']]]]]]]]]]]]]]], [4, ''], [0, '']]

 

这令我相当失望,同样的表达式在Lisp中的解析结果是(+ 2 2)。看来,只有真正的专家才会想去操纵Python的解析树,相 反,Lisp的解析树对任何人来说都是简单可用。我们任然可以在Python中,通过连接字符串,来创建一些类似于宏的东西,但是它不能和其他语言集成, 所以在实践中不这样做。在Lisp中,两个使用宏的主要目的是:新的控制结构和定制针对特定问题的语言。前者没有在Python中实现。后者可以通过在 Python中,用适合特定问题的数据格式来做到:下面我在Python中定义了一个上下文无关语法,分别通过1)组合字典的内置语法,2)解析字符串的 预处理过程完成的。第一种方式和Lisp的宏一样优雅。但是对于复杂的任务,例如为逻辑编程语言写一个编译器这样的事,在Lisp中很容易,但是在 Python将很困难。 

比较Lisp和Python程序

我从《Paradigms of Artificial Intelligence Programming》一书中取了一个简单的随机句子生产器程序,并把它翻译成Python。结论:简介性相当;Python因为grammar[phrase]比 (rule-rhs (assoc phrase *grammar*))简单,而获得一分,但是Lisp因为'(NP VP)比['NP', 'VP']更简介而扳平比分。Python程序很可能比较低效,但是这不是我们关注的点。两个语言看起来都很适合这样的程序。调整浏览器窗口到合适的宽度以便阅读代码。

Lisp程序 simple.lisp   Python程序 simple.py  

(defparameter *grammar*  '((sentence -> (noun-phrase verb-phrase))    (noun-phrase -> (Article Noun))    (verb-phrase -> (Verb noun-phrase))    (Article -> the a)    (Noun -> man ball woman table)    (Verb -> hit took saw liked))  "A grammar for a trivial subset of English.") (defun generate (phrase)  "Generate a random sentence or phrase"  (cond ((listp phrase)         (mappend #'generate phrase))        ((rewrites phrase)         (generate (random-elt (rewrites phrase))))        (t (list phrase)))) (defun generate-tree (phrase)  "Generate a random sentence or phrase,  with a complete parse tree."  (cond ((listp phrase)         (mapcar #'generate-tree phrase))        ((rewrites phrase)         (cons phrase               (generate-tree (random-elt (rewrites phrase)))))        (t (list phrase)))) (defun mappend (fn list)  "Append the results of calling fn on each element of list.  Like mapcon, but uses append instead of nconc."  (apply #'append (mapcar fn list))) (defun rule-rhs (rule)  "The right hand side of a rule."  (rest (rest rule))) (defun rewrites (category)  "Return a list of the possible rewrites for this category."  (rule-rhs (assoc category *grammar*)))

 

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/37dc91ff17a60ff90e5552368dcab356.html