<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
在我的職業生涯中,我寫過、用過和看到過很多隨意的指令碼。一些人需要半自動化完成任務,於是它們誕生了。一段時間後,它們變得越來越大。它們在一生中可能轉手很多次。我常常希望這些指令碼提供更多的 命令列工具式 的感覺。但是,從一次性指令碼到合適的工具,真正提高質量水平有多難呢?事實證明這在 Python 中並不難。
在本文中,我將從一小段 Python 程式碼開始。我將把它應用到 scaffold
模組中,並使用 click
庫擴充套件它以接受命令列引數。
#!/usr/bin/python from glob import glob from os.path import join, basename from shutil import move from datetime import datetime from os import link, unlink LATEST = 'latest.txt' ARCHIVE = '/Users/mark/archive' INCOMING = '/Users/mark/incoming' TPATTERN = '%Y-%m-%d' def transmogrify_filename(fname): bname = basename(fname) ts = datetime.now().strftime(TPATTERN) return '-'.join([ts, bname]) def set_current_latest(file): latest = join(ARCHIVE, LATEST) try: unlink(latest) except: pass link(file, latest) def rotate_file(source): target = join(ARCHIVE, transmogrify_filename(source)) move(source, target) set_current_latest(target) def rotoscope(): file_no = 0 folder = join(INCOMING, '*.txt') print(f'Looking in {INCOMING}') for file in glob(folder): rotate_file(file) print(f'Rotated: {file}') file_no = file_no + 1 print(f'Total files rotated: {file_no}') if __name__ == '__main__': print('This is rotoscope 0.4.1. Bleep, bloop.') rotoscope()
本文所有沒有在這裡插入顯示的程式碼範例,你都可以在 https://codeberg.org/ofosos/rotoscope 中找到特定版本的程式碼。該倉庫中的每個提交都描述了本文操作過程中一些有意義的步驟。
這個片段做了幾件事:
INCOMING
ARCHIVE
ARCHIVE/latest.txt
作為一個範例,它很簡單,但它會讓你理解這個過程。
首先,你需要安裝 scaffold
、 click
和 tox
Python 庫 。
$ python3 -m pip install scaffold click tox
安裝 scaffold
後,切換到範例的 rotoscope
專案所在的目錄,然後執行以下命令:
$ putup rotoscope -p rotoscope --force --no-skeleton -n rotoscope -d 'Move some files around.' -l GLWT -u http://codeberg.org/ofosos/rotoscope --save-config --pre-commit --markdown
Pyscaffold 會重寫我的 README.md
,所以從 Git 恢復它:
$ git checkout README.md
Pyscaffold 在檔案中說明了如何設定一個完整的範例專案,我不會在這裡介紹,你之後可以探索。除此之外,Pyscaffold 還可以在專案中為你提供持續整合(CI)模板:
setup.cfg
檔案解決了這個問題,它包含所有依賴項。檢視測試資料夾並在專案目錄中執行 tox
命令,它會立即輸出一個錯誤:打包基礎設施無法找到相關庫。
現在建立一個 Git
標記(例如 v0.2
),此工具會將其識別為可安裝版本。在提交更改之前,瀏覽一下自動生成的 setup.cfg
並根據需要編輯它。對於此範例,你可以修改 LICENSE
和專案描述,將這些更改新增到 Git 的暫存區,我必須禁用預提交勾點,然後提交它們。否則,我會遇到錯誤,因為 Python 風格檢查器 flake8 會抱怨糟糕的格式。
$ PRE_COMMIT_ALLOW_NO_CONFIG=1 git commit
如果這個指令碼有一個入口點,使用者可以從命令列呼叫,那就更好了。現在,你只能通過找 .py
檔案並手動執行它來執行。幸運的是,Python 的打包基礎設施有一個很好的“罐裝”方式,可以輕鬆地進行設定更改。將以下內容新增到 setup.cfg
的 options.entry_points
部分:
console_scripts = roto = rotoscope.rotoscope:rotoscope
這個更改會建立一個名為 roto
的 shell 命令,你可以使用它來呼叫 rotoscope 指令碼,使用 pip
安裝 rotoscope 後,可以使用 roto
命令。
就是這樣,你可以從 Pyscaffold 免費獲得所有打包、測試和檔案設定。你還獲得了一個預提交勾點來保證(大部分情況下)你按照設定規則提交。
現在,一些值會寫死到指令碼中,它們作為命令 引數 會更方便。例如,將 INCOMING
常數作為命令列引數會更好。
首先,匯入 click 庫,使用 Click 提供的命令裝飾器對 rotoscope()
方法進行裝飾,並新增一個 Click 傳遞給 rotoscope
函數的引數。Click 提供了一組驗證器,因此要向引數新增一個路徑驗證器。Click 還方便地使用函數的內嵌字串作為命令列檔案的一部分。所以你最終會得到以下方法簽名:
@click.command() @click.argument('incoming', type=click.Path(exists=True)) def rotoscope(incoming): """ Rotoscope 0.4 - Bleep, blooop. Simple sample that move files. """
主函數會呼叫 rotoscope()
,它現在是一個 Click 命令,不需要傳遞任何引數。
選項也可以使用 環境變數 自動填充。例如,將 ARCHIVE
常數改為一個選項:
@click.option('archive', '--archive', default='/Users/mark/archive', envvar='ROTO_ARCHIVE', type=click.Path())
使用相同的路徑驗證器。這一次,讓 Click 填充環境變數,如果環境變數沒有提供任何內容,則預設為舊常數的值。
Click 可以做更多的事情,它有彩色的控制檯輸出、提示和子命令,可以讓你構建複雜的 CLI 工具。瀏覽 Click 檔案會發現它的更多功能。
現在新增一些測試。
Click 對使用 CLI 執行器 執行端到端測試 提供了一些建議。你可以用它來實現一個完整的測試(在 範例專案 中,測試在 tests
資料夾中。)
測試位於測試類的一個方法中。大多數約定與我在其他 Python 專案中使用的非常接近,但有一些細節,因為 rotoscope 使用 click
。在 test
方法中,我建立了一個 CliRunner
。測試使用它在一個隔離的檔案系統中執行此命令。然後測試在隔離的檔案系統中建立 incoming
和 archive
目錄和一個虛擬的 incoming/test.txt
檔案,然後它呼叫 CliRunner,就像你呼叫命令列應用程式一樣。執行完成後,測試會檢查隔離的檔案系統,並驗證 incoming
為空,並且 archive
包含兩個檔案(最新連結和存檔檔案)。
from os import listdir, mkdir from click.testing import CliRunner from rotoscope.rotoscope import rotoscope class TestRotoscope: def test_roto_good(self, tmp_path): runner = CliRunner() with runner.isolated_filesystem(temp_dir=tmp_path) as td: mkdir("incoming") mkdir("archive") with open("incoming/test.txt", "w") as f: f.write("hello") result = runner.invoke(rotoscope, ["incoming", "--archive", "archive"]) assert result.exit_code == 0 print(td) incoming_f = listdir("incoming") archive_f = listdir("archive") assert len(incoming_f) == 0 assert len(archive_f) == 2
要在控制檯上執行這些測試,在專案的根目錄中執行 tox
。
在執行測試期間,我在程式碼中發現了一個錯誤。當我進行 Click 轉換時, rotoscope
只是取消了最新檔案的連結,無論它是否存在。測試從一個新的檔案系統(不是我的主資料夾)開始,很快就失敗了。我可以通過在一個很好的隔離和自動化測試環境中執行來防止這種錯誤。這將避免很多“它在我的機器上正常工作”的問題。
我們可以使用 scaffold
和 click
完成一些高階操作。有很多方法可以升級一個普通的 Python 指令碼,甚至可以將你的簡單實用程式變成成熟的 CLI 工具。
以上就是Python實現指令碼轉換為命令列程式的詳細內容,更多關於Python指令碼轉命令列的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45