我在两个独立的文件中写了两个函数,假设是文件A.lisp和B.lisp,其中两个文件都有一些用于测试的主程序代码,而A.lisp会调用B.lisp中的函数。这意味着直接在A.lisp中使用load
方法将执行B.lisp中的主代码,这不应该发生。在我看来,这些文件太小了,不能用像包这样的东西。
在Common Lisp中有类似Python的if __name__ == "__main__":
内容吗?只有当前文件是主模块(即正在运行的程序)时才会执行包含在此条件中的顶级代码,但如果它作为库导入则不会执行。
答案 0 :(得分:6)
包只是符号的名称空间。他们没有说任何关于加载或编译代码的事情。
Common Lisp在ANSI Common Lisp标准中没有库,模块或类似“主”模块/例程的想法。该标准定义了两个例程PROVIDE
和REQUIRE
。但那些指定并不是很明确。
大多数应用程序和库使用“系统”工具来构造,指定,编译和加载代码。
有一个名为ASDF的'免费'。 '另一个系统定义工具'。对于大多数类型的应用程序,像ASDF这样的工具很有用。对于原始应用程序,您可以使用COMPILE-FILE
和LOAD
等标准函数编写自己的工具。
Nick Levine为ASDF撰写了一个教程(他遗弃的Lisp书籍项目的一部分):Systems。
有几个Lisp实现具有更广泛的工具来创建应用程序(例如使用Clozure Common Lisp编写的Mac OS X应用程序)。
答案 1 :(得分:4)
if __name__ == "__main__":
成语非常特定于Python,甚至Python社区中的一些人也会考虑将它用于测试代码的错误样式。
Common Lisp高度重视REPL中的交互式开发,每次要运行测试时都必须重新加载整个文件。只需将测试放入函数定义而不是顶层,它就可以工作并且更方便。
答案 2 :(得分:2)
评估顶级表单。
您可以定义一个main函数,如下例所示,您可以随意调用该函数:
<强> a.lisp 强>:
(defun main ()
...)
<强> b.lisp 强>:
(load "a.lisp")
(main)
答案 3 :(得分:1)
我真的不知道它在Python中是如何工作的,但它看起来像一个文件
一个模块,两个文件是两个不同的模块。事实并非如此
Common Lisp。如果您没有定义任何包,那么当load
文件时,
所有定义都将在当前包中提供(CL-USER
是
默认)。这更像是将代码粘贴到REPL中。
但是包裹并不是很难使用。
在A.lisp:
(defpackage foo
(:use #:cl)
(:export main))
(in-package :foo)
(defun main ()
(do-some-stuff)
(baz:main some-args))
B.lisp中的:
(defpackage baz
(:use #:cl)
(:export main))
(in-package :baz)
(defun main (some-args)
(do-some-stuff))
你可以读 The Complete Idiot's Guide to Common Lisp Packages 和 PCL chapter on packages