PythonはMySQLのようなテーブルをフォーマットして出力します

参照リンク:https//geek-docs.com/python/python-tutorial/python-prettytable.html#PrettyTable-4(リンクがより詳細に記述されていることを認めます)。

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でさえ、この種のテーブルを出力するためのターミナルテーブルを持っています。たとえば、  RubyはMySQLのようにテーブルをフォーマットして出力しますが、Pythonはどのようにこのような結果をフォーマットして出力しますか?

かなり安定したインストール

pip3 installprettytable

[root@master ~]# pip3 install prettytable
WARNING: 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.whl
Requirement 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.whl
Installing collected packages: wcwidth, prettytable
Successfully installed prettytable-2.0.0 wcwidth-0.2.5

かなり安定したインポート

import prettytable as pt

かなり安定した使用

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)

かなり安定した出力

[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())

<table>
    <tr>
        <th>id</th>
        <th>name</th>
        <th>phone</th>
        <th>age</th>
        <th>sex</th>
        <th>description</th>
        <th>create_time</th>
    </tr>
    <tr>
        <td>1</td>
        <td>zhangsan</td>
        <td>132****2889</td>
        <td>25</td>
        <td>M</td>
        <td>NoDesc</td>
        <td>2020-11-30 20:03:07</td>
    </tr>
    <tr>
        <td>3</td>
        <td>lisi</td>
        <td>152****7873</td>
        <td>18</td>
        <td>F</td>
        <td>None</td>
        <td>2020-11-30 20:08:33</td>
    </tr>
    <tr>
        <td>5</td>
        <td>wangwu</td>
        <td>136****2908</td>
        <td>25</td>
        <td>M</td>
        <td>Nothing</td>
        <td>2020-11-30 20:10:11</td>
    </tr>
    <tr>
        <td>10</td>
        <td>zhaoliu</td>
        <td>138****5322</td>
        <td>15</td>
        <td>M</td>
        <td>Nothing</td>
        <td>2020-11-30 20:12:11</td>
    </tr>
</table>

Webページの表示効果は、コマンドラインの効果と直接似ています。 

可愛らしい他のコマンド

好奇心を持って自分でより多くの情報を探検してください!

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 python3

import os
import sys
import json
import prettytable as pt


# receive compare_template.yaml and auto pretty show compare results
class 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% |
+--------------------------------------------------+-----------+-----------+----------+----------+----------+----------+---------+----------+

 

おすすめ

転載: blog.csdn.net/TomorrowAndTuture/article/details/110404494