如何正确导入sage?
补充说明:我想要把sage作为一个库导入到Python脚本中,而不是在sage的命令行界面里使用,因为我需要它在Django上作为一个服务器运行。
我需要从源代码编译sage吗?
我一直在尝试在我的Python脚本中使用sage。
我的代码看起来是这样的:
#!/usr/bin/env sage -python
from django.shortcuts import render
from django.http import HttpResponse
import sys
from django.http import HttpRequest
from django.template import RequestContext, loaders
from sage.all import *
def index(request):
querystring = request.GET.get('querystring')
return HttpResponse(querystring)
# Create your views here.
但是我遇到了一个错误:没有名为sage.all的模块。
我在命令行中运行
#!/usr/bin/env sage -python
import sys
from sage.all import *
var('x')
print integrate(x,x)
print latex(integrate(sin(x),x))
时没有问题,命令是./sage -python /path/to/script.py
所以我不明白为什么我不能导入sage……
“sage”这个目录确实在Python的路径中,它就在我想要使用它的views.py文件旁边。我尝试把它放在不同的位置,或者把它添加到sys.path中,但都没有成功。任何帮助都非常感谢,这个项目对我来说非常重要。我正在尝试把Sage导入到一个Django项目中。
补充说明:我并不是用./sage -python来运行第二个,而是直接在我的Django本地服务器上运行views.py。
3 个回答
Sage 不是一个纯粹的 Python 库。它需要依赖很多共享库来完成它的工作。其中一些库是根据 CPython API 编译的,并且依赖于 Python 的版本。这就是为什么你不能随便在任何 Python 解释器中使用 import sage.all
的原因。
更重要的是,先停下你手上的事情,想想安全性的问题。在网络服务器上执行任意代码总是会带来麻烦。你觉得你能处理好用户输入吗?不行!你觉得没有人会把这个服务器暴露到互联网吗?不行!这种情况肯定会发生,而且结果会很糟糕。
你有没有试过从你的应用目录里导入所有内容,也就是用这个命令:from yor.app.sage.all import *,假设sage文件夹就在你的应用目录里面。
要使用 from sage.all import *
,你需要在一个 Sage 的环境中,或者至少要有正确的设置。为了确保你有这些设置,可以尝试在你的脚本中添加
from os import environ
print environ
。这样你应该能看到一些像 PYTHONPATH
这样的内容,还有一些 Sage 特有的东西。所以如果你不是像第二个例子那样用 ./sage -python
来运行它(我只是说说,以防你没有这样做),那我就不知道了。你可能会觉得 shebang 行应该已经处理好了这些,但也许它们不接受参数,似乎在不同的操作系统上这个行为是相当不一致的,具体情况可以参考这里。
补充:经过一些讨论,在其他地方,我觉得问题在于你试图用 Python 来运行一个 shell 脚本。这个 Stack Overflow 的问题正好解决了这个问题。
为了让例子更清楚,我现在有两个文件。
$ cat views
#!/usr/bin/env sage -python
from sage.all import *
print permutations(5)
$ cat views.py
import subprocess
subprocess.call(['./views'])
现在我可以把这个当作一个普通的(没有 Sage 环境)Python 进程来运行。
$ python views.py
./views:4: DeprecationWarning: Use the Permutations object instead.
See http://trac.sagemath.org/14772 for details.
print permutations(5)
[[1, 2, 3, 4, 5], [1, 2, 3, 5, 4], [1, 2, 4, 3, 5], [1, 2, 4, 5, 3], [1, 2, 5, 3, 4], [1, 2, 5, 4, 3], [1, 3, 2, 4, 5], [1, 3, 2, 5, 4], [1, 3, 4, 2, 5], [1, 3, 4, 5, 2], [1, 3, 5, 2, 4], [1, 3, 5, 4, 2], [1, 4, 2, 3, 5], [1, 4, 2, 5, 3], [1, 4, 3, 2, 5], [1, 4, 3, 5, 2], [1, 4, 5, 2, 3], ... , [5, 4, 3, 2, 1]]
我相信还有更优雅的方法来做到这一点,但目前我觉得这样对你来说应该足够了。顺便说一下,确保你不要让控制器访问任何旧文件,我不是安全专家。