prettytable:像数据库一样格式化输出内容

楔子

记得 MySQL 吗?如果在 MySQL 命令行查询的话,会以如下的形式进行展示。

同理,prettytable 就是用来将数据按照上述形式进行输出的,我们来看一下用法。

添加表头、添加行、添加列

类似于数据库中的表,有表头、或者说字段名,以及每一行的内容。

from prettytable import PrettyTable

# 传入的["姓名", "年龄", "出处"]相当于表头
tb = PrettyTable(["姓名", "年龄", "出处"])
# 调用add_row添加行记录
tb.add_row(["古明地觉", 16, "东方地灵殿"])
tb.add_row(["椎名真白", 18, "樱花庄的宠物女孩"])
tb.add_row(["坂上智代", 18, "Clannad"])
tb.add_row(["雨宫优子", 16, "悠久之翼"])
tb.add_row(["牧濑红莉栖", 20, "命运石之门"])

# 打印
print(tb)
"""
+------------+------+------------------+
|    姓名    | 年龄 |       出处       |
+------------+------+------------------+
| 牧濑红莉栖 |  20  |    命运石之门    |
|  古明地觉  |  16  |    东方地灵殿    |
|  椎名真白  |  18  | 樱花庄的宠物女孩 |
|  坂上智代  |  18  |     Clannad      |
|  雨宫优子  |  16  |     悠久之翼     |
+------------+------+------------------+
"""

当然我们还可以添加一列。

from prettytable import PrettyTable

tb = PrettyTable()
# 指定表头还可以通过tb.field_names单独指定
tb.field_names = ["姓名", "年龄", "出处"]

# 调用add_row添加行记录
tb.add_row(["古明地觉", 16, "东方地灵殿"])
tb.add_row(["椎名真白", 18, "樱花庄的宠物女孩"])
tb.add_row(["坂上智代", 18, "Clannad"])
tb.add_row(["雨宫优子", 16, "悠久之翼"])
tb.add_row(["牧濑红莉栖", 20, "命运石之门"])

# 调用add_column添加一列:列名、数据
tb.add_column("性别", ["女"] * 5)

# 打印
print(tb)
"""
+------------+------+------------------+------+
|    姓名    | 年龄 |       出处       | 性别 |
+------------+------+------------------+------+
|  古明地觉  |  16  |    东方地灵殿    |  女  |
|  椎名真白  |  18  | 樱花庄的宠物女孩 |  女  |
|  坂上智代  |  18  |     Clannad      |  女  |
|  雨宫优子  |  16  |     悠久之翼     |  女  |
| 牧濑红莉栖 |  20  |    命运石之门    |  女  |
+------------+------+------------------+------+
"""

从数据源中导入数据

prettytable 支持从 csv、数据库、html 等数据源中导入数据。但是说实话,从数据源读取数据我们一般使用 pandas,并且还会伴随着数据处理。而使用 prettytable 一般是为了使得程序中输出的某些信息(比如日志信息)更好的展示,如果只是展示读取的文件内容,还不如用Excel、Navicat等工具查看呢。

import pymysql
from prettytable import from_csv
from prettytable import from_db_cursor


# 从csv中读取数据
with open("xxx.csv") as f:
    tb = from_csv(f)
    print(tb)

# 从数据库中读取数据
conn = pymysql.connect()
cursor = conn.cursor()
cursor.execute("select * from t")
tb = from_db_cursor(cursor)
print(tb)

可以创建数据集进行查看。

输出指定行、指定列

我们也可以输出 table 的指定行、指定列。

from prettytable import PrettyTable

tb = PrettyTable()
tb.field_names = ["姓名", "年龄", "出处"]

tb.add_row(["古明地觉", 16, "东方地灵殿"])
tb.add_row(["椎名真白", 18, "樱花庄的宠物女孩"])
tb.add_row(["坂上智代", 18, "Clannad"])
tb.add_row(["雨宫优子", 16, "悠久之翼"])
tb.add_row(["牧濑红莉栖", 20, "命运石之门"])

# fields用于选择输出的列,start和end用于选择输出的开始行和结束行
print(tb.get_string(fields=["姓名", "年龄"], start=1, end=3))
"""
+----------+------+
|   姓名   | 年龄 |
+----------+------+
| 椎名真白 |  18  |
| 坂上智代 |  18  |
+----------+------+
"""

# 此外可以用来进行排序
print(tb.get_string(sortby="年龄", reversesort=True))
"""
+------------+------+------------------+
|    姓名    | 年龄 |       出处       |
+------------+------+------------------+
| 牧濑红莉栖 |  20  |    命运石之门    |
|  椎名真白  |  18  | 樱花庄的宠物女孩 |
|  坂上智代  |  18  |     Clannad      |
|  雨宫优子  |  16  |     悠久之翼     |
|  古明地觉  |  16  |    东方地灵殿    |
+------------+------+------------------+
"""

说实话,也不常用。与其选择性输出,还不如一开始就不要。

设置表格样式

可以通过 set_style 设置样式。

from prettytable import PrettyTable
import prettytable

tb = PrettyTable()
# 指定表头还可以通过tb.field_names单独指定
tb.field_names = ["姓名", "年龄", "出处"]

# 调用add_row添加行记录
tb.add_row(["古明地觉", 16, "东方地灵殿"])
tb.add_row(["椎名真白", 18, "樱花庄的宠物女孩"])
tb.add_row(["坂上智代", 18, "Clannad"])
tb.add_row(["雨宫优子", 16, "悠久之翼"])
tb.add_row(["牧濑红莉栖", 20, "命运石之门"])

# 表格样式有以下几种:DEFAULT、MSWORD_FRIENDLY、PLAIN_COLUMNS、RANDOM
# 我们之前的就是DEFAULT
tb.set_style(prettytable.MSWORD_FRIENDLY)
print(tb)
"""
|    姓名    | 年龄 |       出处       |
|  古明地觉  |  16  |    东方地灵殿    |
|  椎名真白  |  18  | 樱花庄的宠物女孩 |
|  坂上智代  |  18  |     Clannad      |
|  雨宫优子  |  16  |     悠久之翼     |
| 牧濑红莉栖 |  20  |    命运石之门    |
"""
tb.set_style(prettytable.PLAIN_COLUMNS)
print(tb)
"""
   姓名           年龄              出处              
 古明地觉          16            东方地灵殿           
 椎名真白          18         樱花庄的宠物女孩        
 坂上智代          18             Clannad             
 雨宫优子          16             悠久之翼            
牧濑红莉栖         20            命运石之门  
"""
tb.set_style(prettytable.RANDOM)
print(tb)
"""
      古明地觉           16             东方地灵殿        
      椎名真白           18          樱花庄的宠物女孩     
      坂上智代           18              Clannad          
      雨宫优子           16              悠久之翼         
     牧濑红莉栖          20             命运石之门      
"""

说实话,还是默认的DEFAULT最好看。

设置对齐方式

from prettytable import PrettyTable

tb = PrettyTable()
# 指定表头还可以通过tb.field_names单独指定
tb.field_names = ["姓名", "年龄", "出处"]

# 调用add_row添加行记录
tb.add_row(["古明地觉", 16, "东方地灵殿"])
tb.add_row(["椎名真白", 18, "樱花庄的宠物女孩"])
tb.add_row(["坂上智代", 18, "Clannad"])
tb.add_row(["雨宫优子", 16, "悠久之翼"])
tb.add_row(["牧濑红莉栖", 20, "命运石之门"])

# l代表左对齐,c代表居中,r代表右对齐
tb.align["姓名"] = "l"
tb.align["年龄"] = "c"
tb.align["出处"] = "r"

print(tb)
"""
+------------+------+------------------+
| 姓名       | 年龄 |             出处 |
+------------+------+------------------+
| 古明地觉   |  16  |       东方地灵殿 |
| 椎名真白   |  18  | 樱花庄的宠物女孩 |
| 坂上智代   |  18  |          Clannad |
| 雨宫优子   |  16  |         悠久之翼 |
| 牧濑红莉栖 |  20  |       命运石之门 |
+------------+------+------------------+
"""

设置边框样式

在 PrettyTable 中,边框由三个部分组成,横边框,竖边框,和边框连接符(横竖交叉的链接符号)。

from prettytable import PrettyTable

tb = PrettyTable()
# 指定表头还可以通过tb.field_names单独指定
tb.field_names = ["姓名", "年龄", "出处"]

# 调用add_row添加行记录
tb.add_row(["古明地觉", 16, "东方地灵殿"])
tb.add_row(["椎名真白", 18, "樱花庄的宠物女孩"])
tb.add_row(["坂上智代", 18, "Clannad"])
tb.add_row(["雨宫优子", 16, "悠久之翼"])
tb.add_row(["牧濑红莉栖", 20, "命运石之门"])

# 是否显示边框,默认为True
tb.border = True
# 横边框
tb.horizontal_char = '^'
# 竖边框
tb.vertical_char = '>'
# 边框连接符
tb.junction_char='~'

print(tb)
"""
~^^^^^^^^^^^^~^^^^^^~^^^^^^^^^^^^^^^^^^~
>    姓名    > 年龄 >       出处       >
~^^^^^^^^^^^^~^^^^^^~^^^^^^^^^^^^^^^^^^~
>  古明地觉  >  16  >    东方地灵殿    >
>  椎名真白  >  18  > 樱花庄的宠物女孩 >
>  坂上智代  >  18  >     Clannad      >
>  雨宫优子  >  16  >     悠久之翼     >
> 牧濑红莉栖 >  20  >    命运石之门    >
~^^^^^^^^^^^^~^^^^^^~^^^^^^^^^^^^^^^^^^~
"""

我们看到以上的所有示例,貌似输出的都不是很规整啊。其实这是因为我们输出的中文,如果是英文,那么会输出的很漂亮。

from prettytable import PrettyTable

tb = PrettyTable()
# 指定表头还可以通过tb.field_names单独指定
tb.field_names = ["name", "age", "where"]

# 调用add_row添加行记录
tb.add_row(["komeiji satori", 16, "touhou project"])
tb.add_row(["shiina mashiro", 18, "sakurasou"])
tb.add_row(["sakaue tomoyo", 18, "Clannad"])
tb.add_row(["amamiya yuuko", 16, "ef"])
tb.add_row(["makise kurisu", 20, "steins;gate"])

print(tb)
"""
+----------------+-----+----------------+
|      name      | age |     where      |
+----------------+-----+----------------+
| komeiji satori |  16 | touhou project |
| shiina mashiro |  18 |   sakurasou    |
| sakaue tomoyo  |  18 |    Clannad     |
| amamiya yuuko  |  16 |       ef       |
| makise kurisu  |  20 |  steins;gate   |
+----------------+-----+----------------+
"""

小结

总的来说,在打印结构化日志信息的时候,这个库还是很有用的,当然我们也可以自己实现一个。除了这个这个 prettytable 之外,还有一个 pretty_errors,这个库是专门用来美化输出的异常信息的,举个栗子。

import pretty_errors  # 只需要导入这个库即可


def f():
    g()

def g():
    h()

def h():
    1 / 0


f()

这个库实际上是将异常信息进行删减,并做了高亮、加粗显示,当然这个库我们也可以自己实现,核心部分就是重写 sys.excepthook 函数,有兴趣可以自己研究一下。

posted @ 2020-03-23 21:07  古明地盆  阅读(2383)  评论(1编辑  收藏  举报