程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

2 行代碼為 Python 腳本生成命令行,So easy

編輯:Python

前言

有時候我們會有這樣的一個需求:

我們定義了一個 Python 的方法,方法接收一些參數,但是調用的時候想將這些參數用命令行暴露出來。

比如說這裡有個爬取方法:

Python學習交流Q群:903971231###
import requests
def scrape(url, timeout=10):
response = requests.get(url, timeout=timeout)
print(response.text)

這裡定義了一個 scrape 方法,第一個參數接收 url,即爬取的網址,第二個參數接收 timeout,即指定超時時間。

調用的時候我們可能這麼調用:

scrape('https:///www.baidu.com', 10)

如果我們想改參數換 url,那就得改代碼對吧。

所以有時候我們就想把這些參數用命令行暴露出來,這時候我們可能就用上了 argparse 等等的庫,挨個聲明各個參數是干嘛的,

非常繁瑣,代碼如下:

python學習交流Q群:903971231###
parser = argparse.ArgumentParser(description='Scrape Function')
parser.add_argument('url', type=str,
help='an integer for the accumulator')
parser.add_argument('timeout', type=int,
help='sum the integers (default: find the max)')
if __name__ == '__main__':
args = parser.parse_args()
scrape(args.url, args.timeout)

這樣我們才能順利地使用命令行來調用這個腳本:

python3 main.py https://www.baidu.com 10

是不是感覺非常麻煩?argparse 寫起來又臭又長,想想就費勁。

Fire

但接下來我們要介紹一個庫,用它我們只需要兩行代碼就可以做到如上操作。

這個庫的名字叫做Fire,它可以快速為某個 Python 方法或者類添加命令行的參數支持。

先看看安裝方法,使用 pip3 安裝即可:

pip3 install fire

這樣我們就安裝好了。

使用

下面我們來看幾個例子。

方法支持

第一個代碼示例如下:

import fire
def hello(name="World"):
return "Hello %s!" % name
if __name__ == '__main__':
fire.Fire(hello)

這裡我們定義了一個 hello 方法,然後接收一個 name 參數,默認值是 World,接著輸出了 Hello 加 name 這個字符串。

然後接著我們導入了 fire 這個庫,調用它的 Fire 方法並傳入 hello 這個方法聲明,會發生什麼事情呢?

我們把這段代碼保存為 demo1.py,接著用 Python3 來運行一下:

python3 demo1.py

運行結果如下:

Hello World!

看起來並沒有什麼不同。

但我們這時候如果運行如下命令,就可以看到一些神奇的事情了:

python3 demo1.py --help

運行結果如下:

NAME
demo1.py
SYNOPSIS
demo1.py <flags>
FLAGS
--name=NAME
Default: 'World'

可以看到,這裡它將 name 這個參數轉化成了命令行的一個可選參數,我們可以通過 —-name 來替換 name 參數。

我們來試下:

python3 demo1.py --name 123

這裡我們傳入了一個 name 參數是 123,這時候我們就發現運行結果就變成了如下內容:

Hello 123!

是不是非常方便?我們沒有借助 argparse 就輕松完成了命令行參數的支持和替換。

那如果我們將 name 這個參數的默認值取消呢?代碼改寫如下:

import fire
def hello(name):
return "Hello %s!" % name
if __name__ == '__main__':
fire.Fire(hello)

這時候重新運行:

python3 demo1.py --help

就可以看到結果變成了如下內容:

NAME
demo1.py
SYNOPSIS
demo1.py NAME
POSITIONAL ARGUMENTS
NAME
NOTES
You can also use flags syntax for POSITIONAL ARGUMENTS

這時候我們發現 name 這個參數就變成了必傳參數,我們必須在命令行裡指定這個參數內容,調用就會變成如下命令:

python3 demo1.py 123

運行結果還是一樣的。

類支持

當然 fire 這個庫不僅僅支持給方法添加命令行的支持,還支持給一個類添加命令行的支持。

下面我們再看一個例子:

import fire
class Calculator(object):
def double(self, number):
return 2 * number
if __name__ == '__main__':
fire.Fire(Calculator)

我們把這個代碼保存為 demo2.py,然後運行:

python3 demo2.py

運行結果如下:

NAME
demo2.py
SYNOPSIS
demo2.py COMMAND
COMMANDS
COMMAND is one of the following:
double

可以看到,這裡它將 Calculator 這個類中的方法識別出來了,COMMAND 之一就是 double,我們試著調用下:

python3 demo2.py double

運行結果如下:

ERROR: The function received no value for the required argument: number
Usage: demo2.py double NUMBER
For detailed information on this command, run:
demo2.py double --help

這裡就說了,這裡必須要指定另外一個參數,叫做 NUMBER,同時這個參數還是必填參數,我們試著加下:

python3 demo2.py double 4

運行結果如下:

8

這時候就可以達到正確結果了。

所以說,綜合來看,fire 可以為一個類命令行,每個命令都對應一個方法的名稱,同時在後面添加額外的可選或必選參數,加到命

令行參數的後面。

重新改寫

最後,讓我們回過頭來,給我們一開始定義的 scrape 方法添加命令行的參數支持:

import requests
import fire
def scrape(url, timeout=10):
response = requests.get(url, timeout=timeout)
print(response.text)
if __name__ == '__main__':
fire.Fire(scrape)

這樣就可以了!省去了冗長的 argparse 的代碼,是不是非常方便?

調用就是如下形式:

NAME
main.py
SYNOPSIS
main.py URL <flags>
POSITIONAL ARGUMENTS
URL
FLAGS
--timeout=TIMEOUT
Default: 10

這裡說了,URL 是必傳參數,timeout 是可選參數。

最後調用下:

在這裡插入代碼片
python3 main.py https://www.baidu.com

這樣我們就可以輕松將 url 通過命令行傳遞過去了。

當然 timeout 還是可選值,我們可以通過 —-timeout 來指定 timeout 參數:

python3 main.py https://www.baidu.com --timeout 5

最後

這樣兩個參數就都能順利賦值了,最後效果就是爬取百度,5 秒超時。

怎麼樣?是不是很方便?大家快用起來吧!


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved