[ ]
宙飒天下网-ZhouSa.com 1. 自定义交互式界面(cmd)
有时候我们希望我们的服务有一个可交互的客户端,就像数据库操作.
Python提供了交互界面的自定义功能,通过cmd模块我们可以将一些指令放入交互界面中,便于直接调用
我们制作一个python自带的绘图工具turtle的交互界面作为例子:
%%writefile src/turtleshell.py #!/usr/bin/env python # --*-- coding:utf-8 --*-- from __future__ import print_function import cmd, sys from turtle import * class TurtleShell(cmd.Cmd): intro = 'Welcome to the turtle shell. Type help or ? to list commands.\n' prompt = '(turtle) ' file = None # ----- basic turtle commands ----- def do_forward(self, arg): 'Move the turtle forward by the specified distance: FORWARD 10' forward(*parse(arg)) def do_right(self, arg): 'Turn turtle right by given number of degrees: RIGHT 20' right(*parse(arg)) def do_left(self, arg): 'Turn turtle left by given number of degrees: LEFT 90' left(*parse(arg)) def do_goto(self, arg): 'Move turtle to an absolute position with changing orientation. GOTO 100 200' goto(*parse(arg)) def do_home(self, arg): 'Return turtle to the home position: HOME' home() def do_circle(self, arg): 'Draw circle with given radius an options extent and steps: CIRCLE 50' circle(*parse(arg)) def do_position(self, arg): 'Print the current turle position: POSITION' print('Current position is %d %d\n' % position()) def do_heading(self, arg): 'Print the current turle heading in degrees: HEADING' print('Current heading is %d\n' % (heading(),)) def do_color(self, arg): 'Set the color: COLOR BLUE' color(arg.lower()) def do_undo(self, arg): 'Undo (repeatedly) the last turtle action(s): UNDO' def do_reset(self, arg): 'Clear the screen and return turtle to center: RESET' reset() def do_bye(self, arg): 'Stop recording, close the turtle window, and exit: BYE' print('Thank you for using Turtle') self.close() bye() return True # ----- record and playback ----- def do_record(self, arg): 'Save future commands to filename: RECORD rose.cmd' self.file = open(arg, 'w') def do_playback(self, arg): 'Playback commands from a file: PLAYBACK rose.cmd' self.close() with open(arg) as f: self.cmdqueue.extend(f.read().splitlines()) def precmd(self, line): line = line.lower() if self.file and 'playback' not in line: print(line, file=self.file) return line def close(self): if self.file: self.file.close() self.file = None def parse(arg): 'Convert a series of zero or more numbers to an argument tuple' return tuple(map(int, arg.split())) if __name__ == '__main__': TurtleShell().cmdloop()
Writing src/turtleshell.py
在命令行运行下试试
(turtle) CIRCLE 50 (turtle) bye
接着是一个支持sqlite,mysql,pg的命令行客户端
%%writefile src/sqlshell.py #!/usr/bin/env python3 import argparse import cmd, sys import pandas as pd import readline from playhouse.db_url import connect class SqlShell(cmd.Cmd): def __init__(self,completekey='tab', stdin=None, stdout=None,sql_uri=None): super().__init__(completekey=completekey, stdin=stdin, stdout=stdout) self.uri = sql_uri or "sqlite:///:memory:" self.db = connect(self.uri) self.db.connect() self.intro = 'Welcome to the sql shell. Type help or ? to list commands.\n' self.prompt = "("+self.uri.split("://")[0]+" <<<)" self.file = None self.sql_string = "" def _run_sql(self): try: q = self.db.execute_sql(self.sql_string,require_commit=False) except Exception as e: print(type(e)) print(str(e)) else: if q.description: titles = [i[0] for i in q.description] rows = q.fetchall() t = [{t:v for (t,v) in zip(titles,i)} for i in rows] table = pd.DataFrame(t) print("+++++++++++Result+++++++++++") print(table.to_string()) #print(titles) #print(rows) print("++++++++++++++++++++++++++++") else: print('done!') # ----- basic turtle commands ----- def default(self, string): self.sql_string += string.strip() if self.sql_string.endswith(";"): print(self.sql_string) self._run_sql() self.sql_string = "" def do_uri(self, arg): print(self.uri) def do_bye(self, arg): 'Stop recording, close the sqlshell window, and exit: BYE' print('Thank you for using This tool') self.close() self.db.close() return True def do_exit(self, arg): return self.do_bye(arg) def do_quit(self, arg): return self.do_bye(arg) # ----- record and playback ----- def do_record(self, arg): 'Save future commands to filename: RECORD rose.cmd' self.file = open(arg, 'w') def do_playback(self, arg): 'Playback commands from a file: PLAYBACK rose.cmd' self.close() with open(arg) as f: self.cmdqueue.extend(f.read().splitlines()) def precmd(self, line): line = line.lower() if self.file and 'playback' not in line: print(line, file=self.file) return line def close(self): if self.file: self.file.close() self.file = None def shell(args): SqlShell(sql_uri = args.dburi).cmdloop() def main(argv): parser = argparse.ArgumentParser() parser.add_argument("-d","--dburi", help=u"指定dburi",type=str) parser.set_defaults(func=shell) args = parser.parse_args(argv) args.func(args) if __name__ == '__main__': main(argv=sys.argv[1:])
Writing src/sqlshell.py
还没有评论,来说两句吧...