簡體   English   中英

Python:從 arg 解析器到字典

[英]Python: From arg parser to dictionary

我在 Python 3.8 中有一個名為“stores.py”的文件,該文件有一個名為“scan_transactions”的方法,它需要 2 個位置 arguments:“存儲”和“檢查點”。 該方法基本上通過使用 REGEX 模式掃描 PostgreSQL 表中的存儲事務。 當代碼到達事務表中該特定存儲的最后一個事務 id 時,然后使用並更新另一個表(檢查點表)以指示任何給定存儲的最新最大事務 id 是什么。

目前,我正在從類似於下面的預定義字典中傳遞 arguments :

dict_stores = {'store1': 'checkpoint_store1', 'store2': 'checkpoint_store2','store3': 'checkpoint_store3'}

目前代碼如下所示:

def store_transactions(store: str, checkpoint_name: str)
.
.
.
.
.

if __name__ == '__main__':

    for store, checkpoint in shops.dict_stores.items():
        LOG.debug(f'Processing store : {store}, checkpoint: {checkpoint}')
        store_transactions(store, checkpoint)

我現在希望使其更具動態性,並允許用戶在執行之前將他們想要處理交易的商店作為批處理作業傳遞。 這將使用下面的命令行:

"stores.py" --stores -store1 -store2 -store3...etc.

然后上面的命令將替換這個預先固定的字典並動態創建一個字典。 有誰知道我如何使用“arg parser”以某種方式以編程方式將 arguments“-shop 1”、“-shop2”轉換為像上面那樣的字典(將它們各自的檢查點作為值)並使用相同的循環處理所有商店我目前正在運行?

我發現使用拆分,結構來讀取可能性列表很方便

def parse_args(args_external=None):
    """ build an arguments object with required attributes from user input """

    parser = argparse.ArgumentParser(
        description="Example Program",
    )

    parser.add_argument(
        "--foo",
        default="",
        help="comma-separated collection of bars")

    arguments = parser.parse_args(args_external)  # enables automated testing (otherwise None -> sys.argv)

    _foo = []
    for bar in arguments.foo.split(","):
        if not bar:  # allow skipping ,,
            continue
        validatebar(bar)  # sys.exit with message if invalid
    arguments.foo = _foo  # clobber the original reference

這是消耗的

python3 ./myscript.py --foo bar1,bar2,bar3

請注意,我認為您需要使用位置argparse arguments 讓它們重復(即您沒有 --store 選項名稱)。 或者我可能對 optparse 感到困惑,這些天主要使用 Click。

文檔的nargs部分涵蓋了這一點,因此看起來您也可以使用--store 例子不是很清楚。 也就是說,這對用戶來說是更多的打字,所以我會 go 與位置。

import argparse

#the existing dictionary
lookup = {'store1': 'checkpoint_store1', 'store2': 'checkpoint_store2','store3': 'checkpoint_store3'}

#from doc @ https://docs.python.org/3/library/argparse.html#example
parser = argparse.ArgumentParser(description='Process some stores.')

#Option 1 your loop checks for valid stores
# parser.add_argument('stores', type=str, nargs='+', help='stores')

#Option2 argparse checks for valid stores
parser.add_argument('stores', type=str, nargs='+', help='stores', choices=lookup.keys())

args = parser.parse_args()
user_stores = args.stores
dict_stores = {}

#check in loop
for store in user_stores:
    try:
        dict_stores[store] = lookup[store]
    #pragma: no cover pylint: disable=unused-variable
    except (KeyError,) as e: 
        print(f" unknown store {store}. known : {' '.join(lookup.keys())}")

# if you use argparse to check this can be simplified to
# dict_stores[store] = {store: lookup[store] for store in user_stores}


print(f"{dict_stores}")

output:

(venv38) me@explore$ py test_301_arg.py store1 store2
{'store1': 'checkpoint_store1', 'store2': 'checkpoint_store2'}


(venv38) me@explore$ py test_301_arg.py store1 store4
usage: test_301_arg.py [-h] {store1,store2,store3} [{store1,store2,store3} ...]
test_301_arg.py: error: argument stores: invalid choice: 'store4' (choose from 'store1', 'store2', 'store3')


(venv38) me@explore$ py test_301_arg.py --help
usage: test_301_arg.py [-h] {store1,store2,store3} [{store1,store2,store3} ...]

Process some stores.

positional arguments:
  {store1,store2,store3}
                        stores

optional arguments:
  -h, --help            show this help message and exit

替代解決方案:只需讀取stdin配置文件,也許將參數設置為文件名或標准輸入的觸發器

import json

    ...
    with open(path_config) as fh:
        config = json.load(fh)  # config is now a Python dict

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM