<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          強大的 Python 任務自動化工具!invoke 十分鐘入門指南

          共 6106字,需瀏覽 13分鐘

           ·

          2020-04-16 23:22

          作者丨豌豆花下貓
          來源丨Python貓?(python_cat
          nox 的作者在去年的 Pycon US 上,做了一場題為《Break the Cycle: Three excellent Python tools to automate repetitive tasks》的分享(B站觀看地址:https://b23.tv/av86640235),她介紹了三個任務自動化工具:tox、nox 和 invoke,本文的話題正好就是最后的 invoke。78d7a17abbe127cb2b72aa0d39213f42.webp

          1、invoke 可以做什么?

          invoke 是從著名的遠程部署工具 Fabric 中分離出來的,它與 paramiko 一起是 Fabric 的兩大最核心的基礎組件。除了作為命令行工具,它專注于“任務執(zhí)行”(task execution),可以標注和組織任務,并通過 CLI(command-line interface,即命令行界面) 和 shell 命令來執(zhí)行任務。同樣是任務自動化工具,invoke 與我們之前介紹過的 tox/nox 在側重點上有所不同:
          • tox/nox 主要是在打包、測試、持續(xù)集成等方面的自動化(當然它們能做的還不止于此)
          • invoke 則更具普遍性,可以用在任何需要“執(zhí)行任務”的場景,可以是無相關性的任務組,也可以是有順序依賴的分步驟的工作流
          invoke 在 Github 上有 2.7K star,十分受歡迎,接下來我們看看它如何使用?

          2、怎么使用 invoke?

          首先,安裝很簡單:pip install invoke其次,簡單使用時有以下要素:
          • 任務文件。創(chuàng)建一個 tasks.py 文件。
          • @task 裝飾器。在一個函數(shù)上添加 @task 裝飾器,即可將該函數(shù)標記為一個任務,接受 invoke 的調度管理。
          • 上下文參數(shù)。給被裝飾的函數(shù)添加一個上下文參數(shù)(context argument),注意它必須作為第一個參數(shù),而命名按約定可以是cctxcontext 。
          • 命令行執(zhí)行。在命令行中執(zhí)行invoke --list 來查看所有任務,運行invoke xxx 來執(zhí)行名為 xxx 的任務。命令行中的“invoke”可以簡寫成“inv”。
          以下是一個簡單的示例:
          #?文件名:tasks.py
          from?invoke?import?task

          @task
          def?hello(c):
          ????print("Hello?world!")

          @task
          def?greet(c,?name):
          ????c.run(f"echo?{name}加油!")
          在上述代碼中,我們定義了兩個任務:
          • ”hello“任務調用了 Python 內置的 print 函數(shù),會打印一個字符串“Hello world!”
          • “greet”任務調用了上下文參數(shù)的 run() 方法,可以執(zhí)行 shell 命令,同時本例中還可以接收一個參數(shù)。在 shell 命令中,echo 可理解成打印,所以這也是一個打印任務,會打印出“xxx加油!”(xxx 是我們傳的參數(shù))
          以上代碼寫在 tasks.py 文件中,首先導入裝飾器 from invoke import task,@task 裝飾器可以不帶參數(shù),也可以帶參數(shù)(參見下一節(jié)),被它裝飾了的函數(shù)就是一個任務。上下文參數(shù)(即上例的“c”)必須要顯式地指明,如果缺少這個參數(shù),執(zhí)行時會拋出異常:“TypeError: Tasks must have an initial Context argument!”然后在 tasks.py 文件的同級目錄中,打開命令行窗口,執(zhí)行命令。如果執(zhí)行的位置找不到這個任務文件,則會報錯:“Can't find any collection named 'tasks'!”正常情況下,通過執(zhí)行inv --list 或者inv -l ,可以看到所有任務的列表(按字母表順序排序):
          >>>?inv?-l
          Available?tasks:

          ??greet
          ??hello
          我們依次執(zhí)行這兩個任務,其中傳參時可以默認按位置參數(shù)傳參,也可以指定關鍵字傳參。結果是:
          >>>?inv?hello
          Hello?world!
          >>>?inv?greet?武漢
          武漢加油!
          >>>?inv?greet?--name="武漢"
          武漢加油!
          缺少傳參時,報錯:'greet' did not receive required positional arguments: 'name';多余傳參時,報錯:No idea what '???' is!

          3、 如何用好 invoke?

          介紹完 invoke 的簡單用法,我們知道了它所需的幾項要素,也大致知道了它的使用步驟,接下來是它的其它用法。

          3.1 添加幫助信息

          在上例中,“inv -l”只能看到任務名稱,缺少必要的輔助信息,為了加強可讀性,我們可以這樣寫:
          @task(help={'name':?'A?param?for?test'})
          def?greet(c,?name):
          ????"""
          ????A?test?for?shell?command.
          ????Second?line.
          ????"""

          ????c.run(f"echo?{name}加油!")
          其中,文檔字符串的第一行內容會作為摘錄,在“inv -l”的查詢結果中展示,而且完整的內容與 @task 的 help 內容,會對應在“inv --help”中展示:
          >>>?inv?-l
          Available?tasks:

          ??greet???A?test?for?shell?command.
          >>>?inv?--help?greet
          Usage:?inv[oke]?[--core-opts]?greet?[--options]?[other?tasks?here?...]

          Docstring:
          ??A?test?for?shell?command.
          ??Second?line.

          Options:
          ??-n?STRING,?--name=STRING???A?param?for?test

          3.2 任務的分解與組合

          通常一個大任務可以被分解成一組小任務,反過來,一系列的小任務也可能被串連成一個大任務。在對任務作分解、抽象與組合時,這里有兩種思路:
          • 對內分解,對外統(tǒng)一:只定義一個 @task 的任務,作為總體的任務入口,實際的處理邏輯可以抽象成多個方法,但是外部不感知到它們
          • 多點呈現(xiàn),單點匯總:定義多個 @task 的任務,外部可以感知并分別調用它們,同時將有關聯(lián)的任務組合起來,調用某個任務時,也執(zhí)行其它相關聯(lián)的任務
          第一種思路很容易理解,實現(xiàn)與使用都很簡單,但是其缺點是缺少靈活性,難于單獨執(zhí)行其中的某個/些子任務。適用于相對獨立的單個任務,通常也不需要 invoke 就能做到(使用 invoke 的好處是,擁有命令行的支持)。第二種思路更加靈活,既方便單一任務的執(zhí)行,也方便多任務的組合執(zhí)行。實際上,這種場景才是 invoke 發(fā)揮最大價值的場景。那么,invoke 如何實現(xiàn)分步任務的組合呢?可以在 @task 裝飾器的“pre”與“post”參數(shù)中指定,分別表示前置任務與后置任務:
          @task
          def?clean(c):
          ????c.run("echo?clean")

          @task
          def?message(c):
          ????c.run("echo?message")

          @task(pre=[clean],?post=[message])
          def?build(c):
          ????c.run("echo?build")
          clean 與 message 任務作為子任務,可以單獨調用,也可以作為 build 任務的前置與后置任務而組合使用:
          >>>?inv?clean
          clean
          >>>?inv?message
          message
          >>>?inv?build
          clean
          build
          message
          這兩個參數(shù)是列表類型,即可設置多個任務。另外,在默認情況下,@task 裝飾器的位置參數(shù)會被視為前置任務,接著上述代碼,我們寫一個:
          @task(clean,?message)
          def?test(c):
          ????c.run("echo?test")
          然后執(zhí)行,會發(fā)現(xiàn)兩個參數(shù)都被視為了前置任務:
          >>>?inv?test
          clean
          message
          test

          3.3 模塊的拆分與整合

          如果要管理很多相對獨立的大型任務,或者需要多個團隊分別維護各自的任務,那么,就有必要對 tasks.py 作拆分與整合。例如,現(xiàn)在有多份 tasks.py,彼此是相對完整而獨立的任務模塊,不方便把所有內容都放在一個文件中,那么,如何有效地把它們整合起來管理呢?invoke 提供了這方面的支持。首先,只能保留一份名為“tasks.py”的文件,其次,在該文件中導入其它改名后的任務文件,最后,使用 invoke 的 Collection 類把它們關聯(lián)起來。我們把本文中第一個示例文件改名為 task1.py,并新建一個 tasks.py 文件,內容如下:
          #?文件名:tasks.py
          from?invoke?import?Collection,?task
          import?task1

          @task
          def?deploy(c):
          ????c.run("echo?deploy")

          namespace?=?Collection(task1,?deploy)
          每個 py 文件擁有獨立的命名空間,而在此處,我們用 Collection 可以創(chuàng)建出一個新的命名空間,從而實現(xiàn)對所有任務的統(tǒng)一管理。效果如下:
          >>>?inv?-l
          Available?tasks:

          ??deploy
          ??task1.greet
          ??task1.hello
          >>>?inv?deploy
          deploy
          >>>?inv?task1.hello
          Hello?world!
          >>>?inv?task1.greet?武漢
          武漢加油!
          關于不同任務模塊的導入、嵌套、混合、起別名等內容,還有不少細節(jié),請查閱官方文檔了解。

          3.4 交互式操作

          某些任務可能需要交互式的輸入,例如要求輸入“y”,按回車鍵后才會繼續(xù)執(zhí)行。如果在任務執(zhí)行期間需要人工參與,那自動化任務的能力將大打折扣。invoke 提供了在程序運行期的監(jiān)控能力,可以監(jiān)聽stdoutstderr ,并支持在stdin 中輸入必要的信息。例如,假設某個任務(excitable-program)在執(zhí)行時會提示“Are you ready? [y/n]”,只有輸入了“y”并按下回車鍵,才會執(zhí)行后續(xù)的操作。那么,在代碼中指定 responses 參數(shù)的內容,只要監(jiān)聽到匹配信息,程序會自動執(zhí)行相應的操作:
          responses?=?{r"Are?you?ready??\[y/n\]?":?"y\n"}
          ctx.run("excitable-program",?responses=responses)
          responses 是字典類型,鍵值對分別為監(jiān)聽內容及其回應內容。需注意,鍵值會被視為正則表達式,所以像本例中的方括號就要先轉義。

          3.5 作為命令行工具庫

          Python 中有不少好用的命令行工具庫,比如標準庫中的argparse、Flask 作者開源的click 與谷歌開源的fire 等等,而 invoke 也可以作為命令行工具庫使用。(PS:有位 Prodesire 同學寫了“Python 命令行之旅”的系列文章,詳細介紹了其它幾個命令行工具庫的用法,我在公眾號“Python貓”里轉載過大部分,感興趣的同學可查看歷史文章。)事實上,F(xiàn)abric 項目最初把 invoke 分離成獨立的庫,就是想讓它承擔解析命令行與執(zhí)行子命令的任務。所以,除了作為自動化任務管理工具,invoke 也可以被用于開發(fā)命令行工具。官方文檔中給出了一個示例,我們可以了解到它的基本用法。假設我們要開發(fā)一個 tester 工具,讓用戶pip install tester 安裝,而此工具提供兩個執(zhí)行命令:tester unittester intergration 。這兩個子命令需要在 tasks.py 文件中定義:
          #?tasks.py
          from?invoke?import?task

          @task
          def?unit(c):
          ????print("Running?unit?tests!")

          @task
          def?integration(c):
          ????print("Running?integration?tests!")
          然后在程序入口文件中引入它:
          #?main.py
          from?invoke?import?Collection,?Program
          from?tester?import?tasks

          program?=?Program(namespace=Collection.from_module(tasks),?version='0.1.0')
          最后在打包文件中聲明入口函數(shù):
          #?setup.py
          setup(
          ????name='tester',
          ????version='0.1.0',
          ????packages=['tester'],
          ????install_requires=['invoke'],
          ????entry_points={
          ????????'console_scripts':?['tester?=?tester.main:program.run']
          ????}
          )
          如此打包發(fā)行的庫,就是一個功能齊全的命令行工具了:
          $?tester?--version
          Tester?0.1.0
          $?tester?--help
          Usage:?tester?[--core-opts]??[--subcommand-opts]?...

          Core?options:
          ??...?core?options?here,?minus?task-related?ones?...

          Subcommands:
          ??unit
          ??integration

          $?tester?--list
          No?idea?what?'--list'?is!
          $?tester?unit
          Running?unit?tests!
          上手容易,開箱即用,invoke 不失為一款可以考慮的命令行工具庫。更多詳細用法,請查閱文檔 。

          4、小結

          invoke 作為從 Fabric 項目中分離出來的獨立項目,它自身具備一些完整而強大的功能,除了可用于開發(fā)命令行工具,它還是著名的任務自動化工具。本文介紹了它的基礎用法與 5 個方面的中級內容,相信讀者們會對它產(chǎn)生一定的了解。invoke 的官方文檔十分詳盡,限于篇幅,本文不再詳細展開,若感興趣,請自行查閱文檔哦。ce145695c14f04b665bd60c64b9e5c1a.webp作者簡介:豌豆花下貓,生于廣東畢業(yè)于武大,現(xiàn)蘇漂程序員,有一些極客思維,也有一些人文情懷,有一些溫度,還有一些態(tài)度。

          46075fefecf99c8da670349c723de40e.webp

          近期精彩內容推薦:??

          57c4b4fe4d7ed154c6066fd0fa976d70.webp?妹子 rm -rf 把公司整個數(shù)據(jù)庫刪沒了...

          57c4b4fe4d7ed154c6066fd0fa976d70.webp?當互聯(lián)網(wǎng)碼農遇見國企老同學

          57c4b4fe4d7ed154c6066fd0fa976d70.webp?推薦33個IDEA最牛配置,寫代碼太爽了

          57c4b4fe4d7ed154c6066fd0fa976d70.webp?Python中zip()函數(shù)的解釋和可視化




          1a9fd9c26f95ddab6ecfa837aa05a87d.webp

          在看點這里31e0af3747c06deb6d599c2e91364f54.webp好文分享給更多人↓↓

          瀏覽 70
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  女人天堂网 | 97人人澡人人妻人人少妇 | 国产成人三级在线 | 成人视频国产欧美日韩豆花 | 亚洲欧洲精品成人久久奇米网 |