Let’s say that I have created a bunch of Sage code — Sage functions etc. — that I wish to reuse by importing into various Sage scripts. In straight Python, one would put these functions into their own separate file and import them using the usual
from foo import funcname as localfuncname type procedure. It is unclear to me what the proper procedure for doing the same in Sage is — one can’t use the same syntax for a
.sage file, and for example
attach('functions.sage') and only works in interactive Sage and stomps local variables.
However after some Googling and experimentation, I have found one method that behaves in the way that I need: namely that local variables aren’t stomped, and Sage-style syntax, like expressing a rational as a fraction, is preserved. I don’t know if this is the best way to do it, but it seems to be working, so I thought I’d share it.
functions.sage as though it were a module file.
def myfunc(y): var('n, x') z1 = y z2 = 1/2 return z1, z2
Then for the script where we want to use it (
myscript.sage), we preparse the Sage functions file into a Python file and copy it to a name that can be handled before importing it.
import os os.system('sage --preparse functions.sage') os.system('mv functions.sage.py functions.py') from functions import myfunc x = 2 y = 3 z1,z2 = myfunc(y) print(x) print(z2)
myscript.sage produces the following.
From the command-line
$ sage myscript.sage 2 1/2
From an interactive session:
sage: attach('myscript.sage') 2 1/2 sage: type(z2) <type 'sage.rings.rational.Rational'>
The script produces
functions.py, which looks like this:
# This file was *autogenerated* from the file functions.sage from sage.all_cmdline import * # import sage library _sage_const_2 = Integer(2); _sage_const_1 = Integer(1) def myfunc(y): var('n, x') z1 = y z2 = _sage_const_1 /_sage_const_2 return z1, z2
It has been working out for me so far, but it seems a strange way to go about things. I’d welcome any commenters who know of a nicer way.
Refs: Ask Sagemath.org