Python使用Rich?type和TinyDB構(gòu)建聯(lián)系人通訊錄
引言
我們將學(xué)習(xí)如何構(gòu)建一個(gè)終端應(yīng)用程序(CLI應(yīng)用程序)來管理我們的通訊錄
我們將使用type來構(gòu)建CLI應(yīng)用程序,使用Rich來創(chuàng)建彩色終端輸出,使用TinyDB來創(chuàng)建數(shù)據(jù)庫。
工具準(zhǔn)備
我們將在這個(gè)項(xiàng)目中使用一些外部庫。讓我們來了解一下,并逐一安裝。 但是在我們安裝之前,讓我們創(chuàng)建一個(gè)虛擬環(huán)境并激活它。 我們將使用 virtualenv 創(chuàng)建一個(gè)虛擬環(huán)境。Python現(xiàn)在附帶了一個(gè)預(yù)先安裝的virtualenv庫。因此,要?jiǎng)?chuàng)建一個(gè)虛擬環(huán)境,你可以使用下面的命令:
python -m venv env
上面的命令將創(chuàng)建一個(gè)名為env的虛擬環(huán)境?,F(xiàn)在,我們需要使用下面的命令來激活環(huán)境:
. env/Scripts/activate
要驗(yàn)證環(huán)境是否已被激活,可以在終端中看到(env)?,F(xiàn)在,我們可以安裝庫了。
Rich是一個(gè)Python庫,用于向終端編寫富文本(帶有顏色和樣式),并用于顯示高級(jí)內(nèi)容,如表、標(biāo)記和語法高亮顯示代碼。
要安裝Rich,使用以下命令:
pip install Rich
Typer是一個(gè)用于構(gòu)建CLI應(yīng)用程序的庫。
要安裝Typer,使用以下命令:
pip install Typer
TinyDB是一個(gè)純Python編寫的面向文檔的數(shù)據(jù)庫,沒有外部依賴。
要安裝TinyDB,使用下面的命令:
pip install TinyDB
通訊錄特征
我們的通訊錄應(yīng)用程序?qū)⑹且粋€(gè)基于終端的應(yīng)用程序。類似于Todo應(yīng)用程序,我們可以對(duì)其執(zhí)行以下操作:
Add (or Create) : You can add a new contact in the contact book.
Show (or Read) : You can see all your contacts saved in the contact book.
Edit (or Update) : You can edit the contacts saved in the contact book.
Remove (or Delete) : You can delete the contacts saved in the contact book.
如何創(chuàng)建聯(lián)系人模型
首先,我們將為Contact創(chuàng)建一個(gè)自定義類或模型。想想接觸應(yīng)該包含的所有領(lǐng)域。 我能想到這些字段——姓名和聯(lián)系電話。如果您能想到更多,可以將它們添加到您的模型中。我們現(xiàn)在要繼續(xù)調(diào)查這兩位。 創(chuàng)建一個(gè)名為contact_book的目錄。在其中,創(chuàng)建一個(gè)名為model.py的Python文件。在文件中增加如下內(nèi)容:
import datetime class Contact: def __init__ (self, name, contact_number, position=None, date_created=None, date_updated=None): self.name = name self.contact_number = contact_number self.position = position self.date_created = date_created if date_created is not None else datetime.datetime.now().isoformat() self.date_updated = date_updated if date_updated is not None else datetime.datetime.now().isoformat() def __repr__ (self) -> str: return f"({self.name}, {self.contact_number}, {self.position}, {self.date_created}, {self.date_updated})"
我們創(chuàng)建了一個(gè)名為Contact的類,它接受兩個(gè)強(qiáng)制參數(shù):name和contact_number。
除了這兩個(gè)參數(shù)外,它還接受三個(gè)可選參數(shù):position、date_created和date_updated。如果沒有傳遞這三個(gè)可選參數(shù),它們將分別默認(rèn)為當(dāng)前索引和當(dāng)前時(shí)間。
此外,我們還定義了repr方法,該方法以更易于閱讀的方式返回對(duì)象。
如何使用TinyDB創(chuàng)建數(shù)據(jù)庫
現(xiàn)在,讓我們?cè)O(shè)置TinyDB并創(chuàng)建一個(gè)數(shù)據(jù)庫
在contact_book目錄中,創(chuàng)建一個(gè)init.py文件,并添加以下內(nèi)容:
from tinydb import TinyDB, Query db = TinyDB('contact-book.json') db.default_table_name = 'contact-book' ContactQuery = Query()
我們已經(jīng)創(chuàng)建了TinyDB類的一個(gè)實(shí)例,并將文件名傳遞給它。這將創(chuàng)建一個(gè)JSON文件通訊錄。Json,我們的數(shù)據(jù)將被存儲(chǔ)。要從這個(gè)數(shù)據(jù)庫檢索數(shù)據(jù),我們需要一個(gè)tinydb庫中Query類的實(shí)例。
現(xiàn)在,讓我們定義將用于與數(shù)據(jù)庫交互的不同函數(shù)。在contact_book目錄中,創(chuàng)建一個(gè)database.py文件,并在其中添加以下內(nèi)容:
from typing import List import datetime from contact_book.model import Contact from contact_book import db, ContactQuery def create(contact: Contact) -> None: contact.position = len(db)+1 new_contact = { 'name': contact.name, 'contact_number': contact.contact_number, 'position': contact.position, 'date_created': contact.date_created, 'date_updated': contact.date_updated } db.insert(new_contact) def read() -> List[Contact]: results = db.all() contacts = [] for result in results: new_contact = Contact(result['name'], result['contact_number'], result['position'], result['date_created'], result['date_updated']) contacts.append(new_contact) return contacts def update(position: int, name: str, contact_number: str) -> None: if name is not None and contact_number is not None: db.update({'name': name, 'contact_number': contact_number}, ContactQuery.position == position) elif name is not None: db.update({'name': name}, ContactQuery.position == position) elif contact_number is not None: db.update({'contact_number': contact_number}, ContactQuery.position == position) def delete(position) -> None: count = len(db) db.remove(ContactQuery.position == position) for pos in range(position+1, count): change_position(pos, pos-1) def change_position(old_position: int, new_position: int) -> None: db.update({'position': new_position}, ContactQuery.position == old_position)
我們定義了四個(gè)不同的函數(shù)——create()、read()、update()和delete()用于上面提到的每個(gè)操作。我們使用position屬性來識(shí)別特定的聯(lián)系人。change_position()函數(shù)負(fù)責(zé)在刪除聯(lián)系人時(shí)保持聯(lián)系人的位置。
如何使用typer創(chuàng)建命令行
現(xiàn)在讓我們使用type創(chuàng)建CLI。在contact_book目錄之外,創(chuàng)建一個(gè)main.py文件,并添加以下內(nèi)容。如何使用type創(chuàng)建命令行
import typer app = typer.Typer() @app.command(short_help='adds a contact') def add(name: str, contact_number: str): typer.echo(f"Adding {name}, {contact_number}") @app.command(short_help='shows all contacts') def show(): typer.echo(f"All Contacts") @app.command(short_help='edits a contact') def edit(position: int, name: str = None, contact_number: str = None): typer.echo(f"Editing {position}") @app.command(short_help='removes a contact') def remove(position: int): typer.echo(f"Removing {position}") if __name__ == " __main__": app()
首先,我們從類型庫中創(chuàng)建Typer類的一個(gè)實(shí)例。然后,我們?yōu)樯厦嬗懻摰乃膫€(gè)操作創(chuàng)建四個(gè)單獨(dú)的函數(shù)。我們使用@app.command()裝飾器將每個(gè)函數(shù)綁定到一個(gè)命令中。我們還添加了short_help來幫助用戶使用命令。
要添加聯(lián)系人,我們需要name和contact_number參數(shù)。為了展示隱形人,我們什么都不需要。要編輯聯(lián)系人,我們肯定需要位置,而name和contact_number參數(shù)是可選的。要移除接觸點(diǎn),我們只需要位置。
目前,我們沒有在方法內(nèi)部進(jìn)行任何操作。我們只是使用typing類中的echo方法進(jìn)行打印。在main方法中,我們只需要調(diào)用app()對(duì)象。
如果你運(yùn)行這個(gè)應(yīng)用程序,你會(huì)得到一個(gè)類似的輸出:
如何使用Rich設(shè)計(jì)終端
我們希望在一個(gè)漂亮的表格布局中使用不同的顏色顯示聯(lián)系人。Rich 可以幫我們。
現(xiàn)在讓我們修改main.py中的show()函數(shù),因?yàn)樗?fù)責(zé)在終端上打印聯(lián)系人。
from rich.console import Console from rich.table import Table console = Console() @app.command(short_help='shows all contacts') def show(): contacts = [("Ashutosh Krishna", "+91 1234554321"), ("Bobby Kumar", "+91 9876556789")] console.print("[bold magenta]Contact Book[/bold magenta]", "??") if len(contacts) == 0: console.print("[bold red]No contacts to show[/bold red]") else: table = Table(show_header=True, header_style="bold blue", show_lines=True) table.add_column("#", style="dim", width=3, justify="center") table.add_column("Name", min_width=20, justify="center") table.add_column("Contact Number", min_width=12, justify="center") for idx, contact in enumerate(contacts, start=1): table.add_row(str(idx), f'[cyan]{contact[0]}[/cyan]', f'[green]{contact[1]}[/green]') console.print(table)
我們首先創(chuàng)建了Console類的一個(gè)實(shí)例。在show()方法中,我們現(xiàn)在有一個(gè)虛擬的聯(lián)系人列表。使用console對(duì)象,我們用粗體紅色打印標(biāo)題。
接下來,我們創(chuàng)建一個(gè)表并添加列。現(xiàn)在,我們對(duì)聯(lián)系人進(jìn)行迭代,并將它們作為不同顏色的單獨(dú)行放入表中。最后,我們打印表格。
如何使用打字命令連接數(shù)據(jù)庫操作
現(xiàn)在,讓我們進(jìn)行最后一步,將數(shù)據(jù)庫操作與命令連接起來。也就是說,當(dāng)我們運(yùn)行一個(gè)命令時(shí),它應(yīng)該與數(shù)據(jù)庫進(jìn)行適當(dāng)?shù)慕换ァ?/p>
import typer from rich.console import Console from rich.table import Table from contact_book.model import Contact from contact_book.database import create, read, update, delete app = typer.Typer() console = Console() @app.command(short_help='adds a contact') def add(name: str, contact_number: str): typer.echo(f"Adding {name}, {contact_number}") contact = Contact(name, contact_number) create(contact) show() @app.command(short_help='shows all contacts') def show(): contacts = read() console.print("[bold magenta]Contact Book[/bold magenta]", "??") if len(contacts) == 0: console.print("[bold red]No contacts to show[/bold red]") else: table = Table(show_header=True, header_style="bold blue", show_lines=True) table.add_column("#", style="dim", width=3, justify="center") table.add_column("Name", min_width=20, justify="center") table.add_column("Contact Number", min_width=12, justify="center") for idx, contact in enumerate(contacts, start=1): table.add_row(str( idx), f'[cyan]{contact.name}[/cyan]', f'[green]{contact.contact_number}[/green]') console.print(table) @app.command(short_help='edits a contact') def edit(position: int, name: str = None, contact_number: str = None): typer.echo(f"Editing {position}") update(position, name, contact_number) show() @app.command(short_help='removes a contact') def remove(position: int): typer.echo(f"Removing {position}") delete(position) show() if __name__ == " __main__": app()
在上面的代碼中,我們使用了前面創(chuàng)建的create()、read()、update()和delete()。
以上就是Python使用Rich type和TinyDB構(gòu)建聯(lián)系人通訊錄應(yīng)用程序的詳細(xì)內(nèi)容,更多關(guān)于Python構(gòu)建通訊錄的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- Python DBM模塊輕松使用小型數(shù)據(jù)庫存儲(chǔ)管理數(shù)據(jù)
- Python快速進(jìn)修指南之向量數(shù)據(jù)庫文本搜索
- Python?SQLAlchemy與數(shù)據(jù)庫交互操作完整指南
- Python使用cx_Oracle庫連接Oracle數(shù)據(jù)庫指南
- Python連接SQLite數(shù)據(jù)庫操作實(shí)戰(zhàn)指南從入門到精通
- python實(shí)現(xiàn)MySQL?數(shù)據(jù)庫表格創(chuàng)建?數(shù)據(jù)插入及獲取插入ID操作教程
- Python數(shù)據(jù)庫安裝及MySQL?Connector應(yīng)用教程
- python TinyDB輕量級(jí)文檔導(dǎo)向數(shù)據(jù)庫輕松存儲(chǔ)訪問
相關(guān)文章
Python編程中Python與GIL互斥鎖關(guān)系作用分析
GIL互斥鎖用來保護(hù)Python世界里的對(duì)象,防止同一時(shí)刻多個(gè)線程執(zhí)行Python字節(jié)碼,確保線程安全,但也導(dǎo)致Python線程無法利用多核CPU優(yōu)勢(shì),本文來探討Python將來是否有可能去除GIL2021-09-09Python庫學(xué)習(xí)Tkinter制作GUI個(gè)性簽名設(shè)計(jì)軟件
Tkinter 是 Python 中的標(biāo)準(zhǔn) GUI 庫,使用 Tkinter 可以快速地創(chuàng)建 GUI 應(yīng)用程序。今天我們打算再用一個(gè)小案例,帶大家加深對(duì)Tkinter的理解2021-09-09python如何實(shí)時(shí)獲取tcpdump輸出
這篇文章主要介紹了python如何實(shí)時(shí)獲取tcpdump輸出,幫助大家更好的理解和使用python,感興趣的朋友可以了解下2020-09-09Python實(shí)戰(zhàn)之實(shí)現(xiàn)簡(jiǎn)單的名片管理系統(tǒng)
這篇文章主要介紹了Python實(shí)戰(zhàn)之實(shí)現(xiàn)簡(jiǎn)單的名片管理系統(tǒng),文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)python的小伙伴們有非常好的幫助,需要的朋友可以參考下2021-04-04python opencv實(shí)現(xiàn)切變換 不裁減圖片
這篇文章主要為大家詳細(xì)介紹了python opencv實(shí)現(xiàn)切變換,不裁減圖片,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07python實(shí)現(xiàn)從ftp上下載文件的實(shí)例方法
在本篇文章里小編給大家整理了關(guān)于python實(shí)現(xiàn)從ftp上下載文件的實(shí)例方法,需要的朋友們可以參考下。2020-07-07django ListView的使用 ListView中獲取url中的參數(shù)值方式
這篇文章主要介紹了django ListView的使用 ListView中獲取url中的參數(shù)值方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-03-03