博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python 像 MySQL 那样格式化打印表格
阅读量:4229 次
发布时间:2019-05-26

本文共 13772 字,大约阅读时间需要 45 分钟。

参考链接:(我承认链接这个写得更详细)。

我们都知道 MySQL 的输出一般像下边这样的(格式化输出打印,很好看):

mysql> select * from tb_person;+----+----------+-------------+------+------+-------------+---------------------+| id | name     | phone       | age  | sex  | description | create_time         |+----+----------+-------------+------+------+-------------+---------------------+|  1 | zhangsan | 132****2889 |   25 | M    | NoDesc      | 2020-11-30 20:03:07 ||  3 | lisi     | 152****7873 |   18 | F    | None        | 2020-11-30 20:08:33 ||  5 | wangwu   | 136****2908 |   25 | M    | Nothing     | 2020-11-30 20:10:11 || 10 | zhaoliu  | 138****5322 |   15 | M    | Nothing     | 2020-11-30 20:12:11 |+----+----------+-------------+------+------+-------------+---------------------+

就连 Ruby 都有 terminal-table 来输出这种表格,比如说 ,那么 Python 怎么像这样格式化打印结果呢?

prettytable 安装

pip3 install prettytable

[root@master ~]# pip3 install prettytableWARNING: Running pip install with root privileges is generally not a good idea. Try `pip3 install --user` instead.Collecting prettytable  Downloading https://pypi.tuna.tsinghua.edu.cn/packages/94/d5/52e48f3bcf66f838d411ad85c3ac9550c2451d082623e2d4d4df7411ed5c/prettytable-2.0.0-py3-none-any.whlRequirement already satisfied: setuptools in /usr/lib/python3.6/site-packages (from prettytable)Collecting wcwidth (from prettytable)  Downloading https://pypi.tuna.tsinghua.edu.cn/packages/59/7c/e39aca596badaf1b78e8f547c807b04dae603a433d3e7a7e04d67f2ef3e5/wcwidth-0.2.5-py2.py3-none-any.whlInstalling collected packages: wcwidth, prettytableSuccessfully installed prettytable-2.0.0 wcwidth-0.2.5

prettytable 导入

import prettytable as pt

prettytable 使用

import prettytable as pt# 按行添加数据tb = pt.PrettyTable()tb.field_names = ["id", "name", "phone", "age", "sex", "description"]tb.add_row([1, "zhangsan", "132****2889", 25, "M", "NoDesc"])tb.add_row([3, "lisi",     "152****7873", 18, "F", "None"])tb.add_row([5, "wangwu",   "136****2908", 25, "M", "Nothing"])tb.add_row([10,"zhaoliu",  "138****5322", 15, "M", "Nothing"])print(tb)# 按列添加数据create_time = ["2020-11-30 20:03:07", "2020-11-30 20:08:33", "2020-11-30 20:10:11", "2020-11-30 20:12:11"]tb.add_column("create_time", create_time)print(tb)

prettytable 输出

[root@master python3_learning]# python3 test.py+----+----------+-------------+-----+-----+-------------+| id |   name   |    phone    | age | sex | description |+----+----------+-------------+-----+-----+-------------+| 1  | zhangsan | 132****2889 |  25 |  M  |    NoDesc   || 3  |   lisi   | 152****7873 |  18 |  F  |     None    || 5  |  wangwu  | 136****2908 |  25 |  M  |   Nothing   || 10 | zhaoliu  | 138****5322 |  15 |  M  |   Nothing   |+----+----------+-------------+-----+-----+-------------++----+----------+-------------+-----+-----+-------------+---------------------+| id |   name   |    phone    | age | sex | description |     create_time     |+----+----------+-------------+-----+-----+-------------+---------------------+| 1  | zhangsan | 132****2889 |  25 |  M  |    NoDesc   | 2020-11-30 20:03:07 || 3  |   lisi   | 152****7873 |  18 |  F  |     None    | 2020-11-30 20:08:33 || 5  |  wangwu  | 136****2908 |  25 |  M  |   Nothing   | 2020-11-30 20:10:11 || 10 | zhaoliu  | 138****5322 |  15 |  M  |   Nothing   | 2020-11-30 20:12:11 |+----+----------+-------------+-----+-----+-------------+---------------------+

看看,是不是和 MySQL 数据库查询的结果是一样的,惊喜吗?敢动吗?

它还可以输出 html 的格式:

print(tb.get_html_string())
id name phone age sex description create_time
1 zhangsan 132****2889 25 M NoDesc 2020-11-30 20:03:07
3 lisi 152****7873 18 F None 2020-11-30 20:08:33
5 wangwu 136****2908 25 M Nothing 2020-11-30 20:10:11
10 zhaoliu 138****5322 15 M Nothing 2020-11-30 20:12:11

网页显示效果和命令行直接打印的差不多哟! 

prettytable 其他命令

更多信息自己凭着好奇心去探讨哟!

tb.clear()              # 清空对象数据tb.clear_rows()         # 清空数据行(field_names 的设置还是在的)tb.del_row(row_index)   # 删除指定索引的数据行tb.get_html_string()    # 转换成 html 格式tb.field_names = [...]  # 设置字段名tb.border = False       # 是否添加边框(无边框效果如下) id    name       phone     age  sex  description      create_time      1   zhangsan  132****2889   25   M      NoDesc    2020-11-30 20:03:07  3     lisi    152****7873   18   F       None     2020-11-30 20:08:33  10  zhaoliu   138****5322   15   M     Nothing    2020-11-30 20:12:11 tb.header = False       # 是否显示字段行(不显示效果如下)+----+----------+-------------+-------+---+---------+---------------------+| 1  | zhangsan | 132****2889 | 25.23 | M |  NoDesc | 2020-11-30 20:03:07 || 3  |   lisi   | 152****7873 |   18  | F |   None  | 2020-11-30 20:08:33 || 5  |  wangwu  | 136****2908 |   25  | M | Nothing | 2020-11-30 20:10:11 || 10 | zhaoliu  | 138****5322 |   15  | M | Nothing | 2020-11-30 20:12:11 |+----+----------+-------------+-------+---+---------+---------------------+tb.print_empty = True   # 空数据的时候打印表框架还是空字符串(是的效果如下)++||++++tb.align['name'] = 'r'  # name 字段列右对齐...

实例演示

# test.json{  "title": "Hackbench Performance Testing",  "unit": "KB/s",  "x_name": "bs|test_size",  "tables": {    "fio.read_iops": {      "average": {        "dimensions": [          "compare_dimension",          "openeuler 20.03"        ],        "source": [          [            "4k|1G",            "4k|80G",            "16k|1G",            "32k|1G",            "64k|1G",            "128k|1G",            "256k|1G",            "512k|1G",            "1024k|1G"          ],          [            "openeuler 20.03",            144076.2903315,            11601.099817,            37865.30472368628,            21145.10375497826,            14010.34254665909,            6701.240849466667,            3205.077255,            1367.476930860465,            673.3270888666667          ]        ]      },      "standard_deviation": {        "dimensions": [          "compare_dimension",          "openeuler 20.03"        ],        "source": [          [            "4k|1G",            "4k|80G",            "16k|1G",            "32k|1G",            "64k|1G",            "128k|1G",            "256k|1G",            "512k|1G",            "1024k|1G"          ],          [            "openeuler 20.03",            195,            0,            214,            205,            188,            183,            180,            191,            191          ]        ]      }    },    "fio.write_iops": {      "average": {        "dimensions": [          "compare_dimension",          "centos 7.6",          "openeuler 20.03"        ],        "source": [          [            "4k|1G",            "16k|1G",            "32k|1G",            "64k|1G",            "128k|1G",            "256k|1G",            "512k|1G",            "1024k|1G"          ],          [            "centos 7.6",            345243.028251,            142698.794456,            62108.34762725,            34747.729395,            26330.187008999997,            10317.85034025,            7471.708886999999,            3558.2993653999997          ],          [            "openeuler 20.03",            122003.54468561111,            33528.52637123529,            31469.058358695653,            13870.135498022726,            8249.707439577778,            4329.454872088889,            1976.5380473953487,            1141.003158088889          ]        ]      },      "standard_deviation": {        "dimensions": [          "compare_dimension",          "centos 7.6",          "openeuler 20.03"        ],        "source": [          [            "4k|1G",            "16k|1G",            "32k|1G",            "64k|1G",            "128k|1G",            "256k|1G",            "512k|1G",            "1024k|1G"          ],          [            "centos 7.6",            97,            95,            122,            125,            100,            130,            101,            103          ],          [            "openeuler 20.03",            174,            188,            171,            197,            181,            175,            170,            176          ]        ]      },      "change": {        "dimensions": [          "compare_dimension",          "centos 7.6 vs openeuler 20.03"        ],        "source": [          [            "4k|1G",            "16k|1G",            "32k|1G",            "64k|1G",            "128k|1G",            "256k|1G",            "512k|1G",            "1024k|1G"          ],          [            "centos 7.6 vs openeuler 20.03",            183.0,            325.6,            97.4,            150.5,            219.2,            138.3,            278.0,            211.9          ]        ]      }    }  }}
# test.py#!/usr/bin/env python3import osimport sysimport jsonimport prettytable as pt# receive compare_template.yaml and auto pretty show compare resultsclass TableShow:    def __init__(self, result_dict, row_size=8):        self.title = result_dict['title']        self.tables = result_dict['tables']        self.row_size = row_size        self.tb = None    def show_table(self):        for (table_title, table) in self.tables.items():            self.tb = pt.PrettyTable()            self.tb.header = True            self.set_field_names(table, table_title)            self.set_align(table_title)            self.add_row(table)            self.print_table()    def set_field_names(self, table, table_title):        field_names = [table_title]        field_names.extend(table['average']['source'][0])        self.tb.field_names = field_names    def set_align(self, table_title):        for field_name in self.tb.field_names:            self.tb.align[field_name] = 'r'        self.tb.align[table_title] = 'l'    def add_row(self, table):        row_names = ['average', 'standard_deviation', 'change']        max_size = max([len(row_name) for row_name in row_names])        for row_name in row_names:            if row_name not in table:                continue            dimensions_size = len(table[row_name]['dimensions'])            for index in range(1, dimensions_size):                row = table[row_name]['source'][index]                row_title = ' '. join([row_name + ' ' * (max_size - len(row_name)), row[0]])                if row_name == 'change':                    format_data_row = ["%.1f%%" % data for data in row[1:]]                else:                    format_data_row = ["%.2f" % data for data in row[1:]]                self.tb.add_row([row_title, *format_data_row])    def get_row_num(self):        row_num, rem = divmod(len(self.tb.field_names[1:]), self.row_size)        if rem > 0:            row_num += 1        self.tb.row_num = row_num    def print_table(self):        print(self.title)        self.get_row_num()        for row in range(self.tb.row_num):            start = 1 + row * self.row_size            end = start + self.row_size            # set the field names to include in displays            self.tb.fields = [self.tb.field_names[0], *self.tb.field_names[start:end]]            print(self.tb)        print()if __name__ == '__main__':    # template_yaml = sys.argv[1]    # result_dict = json.loads(os.popen(f"compare -t {template_yaml}").read())    result_dict = json.load(open("test.json"))    table_show = TableShow(result_dict, 9)    table_show.show_table()
Hackbench Performance Testing+------------------------------------+-----------+----------+----------+----------+----------+---------+---------+---------+----------+| fio.read_iops                      |     4k|1G |   4k|80G |   16k|1G |   32k|1G |   64k|1G | 128k|1G | 256k|1G | 512k|1G | 1024k|1G |+------------------------------------+-----------+----------+----------+----------+----------+---------+---------+---------+----------+| average            openeuler 20.03 | 144076.29 | 11601.10 | 37865.30 | 21145.10 | 14010.34 | 6701.24 | 3205.08 | 1367.48 |   673.33 || standard_deviation openeuler 20.03 |    195.00 |     0.00 |   214.00 |   205.00 |   188.00 |  183.00 |  180.00 |  191.00 |   191.00 |+------------------------------------+-----------+----------+----------+----------+----------+---------+---------+---------+----------+Hackbench Performance Testing+--------------------------------------------------+-----------+-----------+----------+----------+----------+----------+---------+----------+| fio.write_iops                                   |     4k|1G |    16k|1G |   32k|1G |   64k|1G |  128k|1G |  256k|1G | 512k|1G | 1024k|1G |+--------------------------------------------------+-----------+-----------+----------+----------+----------+----------+---------+----------+| average            centos 7.6                    | 345243.03 | 142698.79 | 62108.35 | 34747.73 | 26330.19 | 10317.85 | 7471.71 |  3558.30 || average            openeuler 20.03               | 122003.54 |  33528.53 | 31469.06 | 13870.14 |  8249.71 |  4329.45 | 1976.54 |  1141.00 || standard_deviation centos 7.6                    |     97.00 |     95.00 |   122.00 |   125.00 |   100.00 |   130.00 |  101.00 |   103.00 || standard_deviation openeuler 20.03               |    174.00 |    188.00 |   171.00 |   197.00 |   181.00 |   175.00 |  170.00 |   176.00 || change             centos 7.6 vs openeuler 20.03 |    183.0% |    325.6% |    97.4% |   150.5% |   219.2% |   138.3% |  278.0% |   211.9% |+--------------------------------------------------+-----------+-----------+----------+----------+----------+----------+---------+----------+

 

转载地址:http://dnjqi.baihongyu.com/

你可能感兴趣的文章
九度OJ 1091:棋盘游戏 (DP、BFS、DFS、剪枝)
查看>>
Openfiler 配置 NFS 示例
查看>>
Oracle 11.2.0.1 RAC GRID 无法启动 : Oracle High Availability Services startup failed
查看>>
Oracle 18c 单实例安装手册 详细截图版
查看>>
Oracle Linux 6.1 + Oracle 11.2.0.1 RAC + RAW 安装文档
查看>>
Oracle 11g 新特性 -- Online Patching (Hot Patching 热补丁)说明
查看>>
Oracle 11g 新特性 -- ASM 增强 说明
查看>>
Oracle 11g 新特性 -- Database Replay (重演) 说明
查看>>
Oracle 11g 新特性 -- 自动诊断资料档案库(ADR) 说明
查看>>
CSDN博客之星 投票说明
查看>>
Oracle wallet 配置 说明
查看>>
Oracle smon_scn_time 表 说明
查看>>
VBox fdisk 不显示 添加的硬盘 解决方法
查看>>
Java多态性理解
查看>>
【屌丝程序的口才逆袭演讲稿50篇】第一篇:互联网时代U盘化生存方式 【张振华.Jack】
查看>>
CentOS6.4配置Hadoop-2.6.0集群配置安装指南(经过实战演练)【张振华.Jack】
查看>>
【屌丝程序的口才逆袭演讲稿50篇】第二篇:专注的力量 [张振华.Jack]
查看>>
BFS——求矩阵中“块”的个数
查看>>
BFS——走迷宫的最小步数
查看>>
并查集——好朋友
查看>>