无论Spyder是否使用QT界面,都不应该与您想要修改的IPython配置文件有关。您选择修改的
ipython_qtconsole_config.py
是在启动
IPython的 QT控制台时加载的配置文件,例如使用命令行命令时。
user@system:~$ ipython qtconsole
我需要更新
pyzmq
才能使其正常工作。
如果
Spyder维护一个正在运行的IPython内核并仅管理如何为您显示它,那么Spyder可能只是维护一个常规的IPython会话,在这种情况下,您希望将配置设置放入与找到
ipython_qtconsole_config.py
相同的目录中的文件
ipython_config.py
中。
我以稍微不同的方式管理这个。在
ipython_config.py
中,我的前几行看起来像这样:
from os.path import join as pjoin
from IPython.utils.path import get_ipython_dir
c = get_config()
c.InteractiveShellApp.exec_files = [
pjoin(get_ipython_dir(), "profile_default", "launch.py")
]
这段代码的作用是为我获取IPython配置目录,添加
profile_default
子目录,然后添加名称为
launch.py
的文件。我创建了这个文件,以便在启动时执行/加载任何我想要的内容。例如,下面是
launch.py
文件的第一部分:
"""
IPython launch script
Author: Ely M. Spears
"""
import re
import os
import abc
import sys
import mock
import time
import types
import pandas
import inspect
import cPickle
import unittest
import operator
import warnings
import datetime
import dateutil
import calendar
import copy_reg
import itertools
import contextlib
import collections
import numpy as np
import scipy as sp
import scipy.stats as st
import scipy.weave as weave
import multiprocessing as mp
from IPython.core.magic import (
Magics,
register_line_magic,
register_cell_magic,
register_line_cell_magic
)
from dateutil.relativedelta import relativedelta as drr
def _pickle_method(method):
func_name = method.im_func.__name__
obj = method.im_self
cls = method.im_class
return _unpickle_method, (func_name, obj, cls)
def _unpickle_method(func_name, obj, cls):
for cls in cls.mro():
try:
func = cls.__dict__[func_name]
except KeyError:
pass
else:
break
return func.__get__(obj, cls)
copy_reg.pickle(types.MethodType, _pickle_method, _unpickle_method)
def interface_methods(*methods):
"""
Class decorator that can decorate an abstract base class with method names
that must be checked in order for isinstance or issubclass to return True.
"""
def decorator(Base):
def __subclasshook__(Class, Subclass):
if Class is Base:
all_ancestor_attrs = [ancestor_class.__dict__.keys()
for ancestor_class in Subclass.__mro__]
if all(method in all_ancestor_attrs for method in methods):
return True
return NotImplemented
Base.__subclasshook__ = classmethod(__subclasshook__)
return Base
def interface(*attributes):
"""
Class decorator checking for any kind of attributes, not just methods.
Usage:
@interface(('foo', 'bar', 'baz))
class Blah
pass
Now, new classes will be treated as if they are subclasses of Blah, and
instances will be treated instances of Blah, provided they possess the
attributes 'foo', 'bar', and 'baz'.
"""
def decorator(Base):
def checker(Other):
return all(hasattr(Other, a) for a in attributes)
def __subclasshook__(cls, Other):
if checker(Other):
return True
return NotImplemented
def __instancecheck__(cls, Other):
return checker(Other)
Base.__metaclass__.__subclasshook__ = classmethod(__subclasshook__)
Base.__metaclass__.__instancecheck__ = classmethod(__instancecheck__)
return Base
return decorator
可能有数十个辅助函数、我认为很酷的代码片段以及想要玩耍的东西等等。我还定义了一些随机生成的玩具数据集,如NumPy数组和Pandas DataFrames,这样当我想要探索某些一次性Pandas语法或其他内容时,就有一些玩具数据可供使用。
另一个好处是因为将自定义导入、函数定义等分离出来,所以如果我想要在笔记本电脑和/或qt控制台中加载相同的内容,我只需添加同样的代码来执行文件launch.py
,并且我可以仅在launch.py
中进行更改,而无需手动将其迁移到三个配置文件中的每个文件。
我还取消了几个不同的设置,特别是对于纯IPython和笔记本电脚本,所以配置文件在意义上互不相同,但不基于我想要在启动时导入哪些模块。