Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
359 views
in Technique[技术] by (71.8m points)

python - Save workspace in IPython

Is it possible to save an IPython workspace (defined functions, different kinds of variables, etc) so that it can be loaded later?

This would be a similar function to save.image() in MATLAB or R. Similar questions has been asked before, such as:

Save session in IPython like in MATLAB?

However, since a few years passed, I am wondering if there is a good solution now.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

EDIT: this answer (and gist) has been modified to work for IPython 6

I added a somewhat ad-hoc solution that automates the process of storing/restoring user space variables using the underlying code from IPython's %store magic which is from what I understand what you wanted. See the gist here. Note that this only works for objects that can be pickled.

I can't guarantee its robustness, especially if any of the autorestore mechanisms in IPython change in the future, but it has been working for me with IPython 2.1.0. Hopefully this will at least point you in the right direction.

To reiterate the solution here:

  1. Add the save_user_variables.py script below to your ipython folder (by default $HOME/.ipython). This script takes care of saving user variables on exit.
  2. Add this line to your profile's ipython startup script (e.g., $HOME/.ipython/profile_default/startup/startup.py):

    get_ipython().ex("import save_user_variables;del save_user_variables")

  3. In your ipython profile config file (by default $HOME/.ipython/profile_default/ipython_config.py) find the following line:

    # c.StoreMagics.autorestore = False

    Uncomment it and set it to true. This automatically reloads stored variables on startup. Alternatively you can reload the last session manually using %store -r.

save_user_variables.py

def get_response(quest,default=None,opts=('y','n'),please=None,fmt=None):
    try:
        raw_input = input
    except NameError:
        pass
    quest += " ("
    quest += "/".join(['['+o+']' if o==default else o for o in opts])
    quest += "): "

    if default is not None: opts = list(opts)+['']
    if please is None: please = quest
    if fmt is None: fmt = lambda x: x

    rin = input(quest)
    while fmt(rin) not in opts: rin = input(please)

    return default if default is not None and rin == '' else fmt(rin)

def get_user_vars():
    """
    Get variables in user namespace (ripped directly from ipython namespace
    magic code)
    """
    import IPython
    ip = IPython.get_ipython()    
    user_ns = ip.user_ns
    user_ns_hidden = ip.user_ns_hidden
    nonmatching = object()
    var_hist = [ i for i in user_ns
                 if not i.startswith('_') 
                 and (user_ns[i] is not user_ns_hidden.get(i, nonmatching)) ]
    return var_hist

def shutdown_logger():
    """
    Prompts for saving the current session during shutdown
    """
    import IPython, pickle
    var_hist = get_user_vars()
    ip = IPython.get_ipython()
    db = ip.db

    # collect any variables that need to be deleted from db
    keys = map(lambda x: x.split('/')[1], db.keys('autorestore/*'))
    todel = set(keys).difference(ip.user_ns)
    changed = [db[k] != ip.user_ns[k.split('/')[1]]
               for k in db.keys('autorestore/*') if k.split('/')[1] in ip.user_ns]

    try:
        if len(var_hist) == 0 and len(todel) == 0 and not any(changed): return
        if get_response("Save session?", 'n', fmt=str.lower) == 'n': return
    except KeyboardInterrupt:
        return

    # Save interactive variables (ignore unsaveable ones)
    for name in var_hist:
        obj = ip.user_ns[name]
        try:
            db[ 'autorestore/' + name ] = obj
        except pickle.PicklingError:
            print("Could not store variable '%s'. Skipping..." % name)
            del db[ 'autorestore/' + name ]

    # Remove any previously stored variables that were deleted in this session
    for k in todel:
        del db['autorestore/'+k]

import atexit
atexit.register(shutdown_logger)
del atexit

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...