覆盖ipython退出函数 - 或者添加钩子

时间:2016-09-14 21:16:04

标签: python shell ipython

在我的项目manage中,我将iPython嵌入:

from IPython import start_ipython
from traitlets.config import Config
c = Config()
c.TerminalInteractiveShell.banner2 = "Welcome to my shell"
c.InteractiveShellApp.extensions = ['autoreload']
c.InteractiveShellApp.exec_lines = ['%autoreload 2']
start_ipython(argv=[], user_ns={}, config=c)

效果很好并打开我的iPython控制台,但要离开ipython,我只需输入exitexit()或按ctrl+D

我想要做的是添加exit hook或用其他内容替换exit命令。

假设我有一个功能。

def teardown_my_shell():
    # things I want to happen when iPython exits

如何在我exit时注册要执行的功能,或者如何让exit执行该功能?

注意:我试图通过user_ns={'exit': teardown_my_shell}但无效。

感谢。

2 个答案:

答案 0 :(得分:4)

首先感谢@ user2357112,我学习了如何创建扩展并注册一个钩子,但我发现import atexit def teardown_my_shell(): # things I want to happen when iPython exits atexit.register(teardown_my_shell) 已被弃用。

正确的方法很简单。

public partial class Service1 : ServiceBase
{
    private readonly PollingService _pollingService = new PollingService();

    public Service1()
    {
        InitializeComponent();
    }

    protected override void OnStart(string[] args)
    {
        _pollingService.StartPolling();
    }

    protected override void OnStop()
    {
       _pollingService.StopPolling();
    }
}

public class PollingService
{
    private Thread _workerThread;
    private AutoResetEvent _finished;
    private const int _timeout = 60 * 1000;
    string command = "5120000000000000000000000000000";


    public void StartPolling()
    {
        _workerThread = new Thread(Poll);
        _finished = new AutoResetEvent(false);
        _workerThread.Start();
    }

    private void Poll()
    {
        while (!_finished.WaitOne(_timeout))
        {
            //do the task
            using (TcpClient newclient = new TcpClient())
            {
                IAsyncResult ar = newclient.BeginConnect("192.168.0.151", 4000, null, null);
                if (!ar.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(2), false))
                {
                    return;
                }

                NetworkStream ns = newclient.GetStream();
                byte[] outbytes = HexStringToByteArray(command);
                ns.Write(outbytes, 0, outbytes.Length);
            }
        }
    }

    public void StopPolling()
    {
        _finished.Set();
        _workerThread.Join();
    }

    public static byte[] HexStringToByteArray(string hexString)
    {
        if (hexString.Length % 2 > 0)
        {
            throw new Exception("Invalid command.");
        }
        byte[] result = new byte[hexString.Length / 2];
        try
        {
            for (int i = 0; i < result.Length; i++)
            {
                result[i] = Convert.ToByte(hexString.Substring(2 * i, 2), 16);
            }
        }
        catch (Exception)
        {
            throw;
        }
        return result;
    }
}

答案 1 :(得分:2)

谷歌搜索IPython exit hook出现IPython.core.hooks。从该文档中,您可以在IPython extension中定义一个退出钩子并使用IPython实例的set_hook方法注册它:

# whateveryoucallyourextension.py

import IPython.core.error

def shutdown_hook(ipython):
    do_whatever()
    raise IPython.core.error.TryNext

def load_ipython_extension(ipython)
    ipython.set_hook('shutdown_hook', shutdown_hook)

您必须将扩展程序添加到c.InteractiveShellApp.extensions