自定义Python Shell

做开发时,总会debug自己的程序,python debub程序绝对离不开pythonshell,这根能发挥出动态语言的特性。

创建一个Python Shell

1
2
3
4
5
6
#!/usr/bin/env python

import sys
import os

os.environ['PYTHONINSPECT'] = 'True'

这是一个原生的python shell。

我们来加一些样式和功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/usr/bin/env python

import sys
import os

#red color
r = "\033[31m"

#whie color
w = "\033[0m"]]"

#clear the terminal
os.system('clear')

#custom prompt
sys.ps1 = r + "[custom] " + w
os.environ['PYTHONINSPECT'] = 'True'

现在,我们的终端不再是>>>,而是红色的[custom],可以尝试一下。

然后我们尝试使用imp来加载modules

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#!/usr/bin/env python

import sys
import os
import __builtin__
import imp

#red color
r = "\033[31m"

#white color
w = "\033[0m"

#clear the terminal
os.system('clear')

#custom prompt
sys.ps1 = r + "[custom] " + w

#load module
def _importmodule(module):
try:
modulename = "modules/" + module + ".py"
ModuleFile = open(modulename, 'rb')
mod = imp.load_source(module, modulename, ModuleFile)

#updating loaded module list
__builtin__.__dict__.update(mod.__dict__)
print w + "Module " + module + " loaded..."

#adding [modulename] to prompt to see which module is currently loaded
sys.ps1 = r + "[custom] " + "<" + module + "> " + w

#closing opened file
finally:
try: ModuleFile.close()
except: pass

#loading method
def loadmodule(mname):
_importmodule(mname)

def unloadmodule(moname):
del sys.modules[moname]
sys.ps1 = r + "[custom] " + w

os.environ['PYTHONINSPECT'] = 'True'

现在可以在shell中使用loadmodule(modulename),来加载模块,尝试下看看输出什么。

我们给python shell加上tab补全功能,这时就要用到readline了。

1
2
3
4
5
6
7
try:
import readline
except ImportError:
print("Module readline not available.")
else:
import rlcompleter
readline.parse_and_bind("tab: complete")

支持python2,3,在终端中试试吧。

Ipython支持

以上做了那么多,其实还可以更简单。

1
2
3
4
5
6
7
8
9
#!/usr/bin/env python
# -*- coding:utf-8 -*-

import os
import IPython

os.environ['PYTHONSTARTUP'] = '' # Prevent running this again
IPython.start_ipython()
raise SystemExit

当然也可以使用bpython等等。

Iptyhon autoreload

.ipython/profile_default下创建文件ipython_config.py,输入以下内容

1
2
3
4
c = get_config()
c.InteractiveShellApp.exec_lines = []
c.InteractiveShellApp.exec_lines.append('%load_ext autoreload')
c.InteractiveShellApp.exec_lines.append('%autoreload 2')