Python:从arg解析器到字典

2024-10-03 02:37:18 发布

您现在位置:Python中文网/ 问答频道 /正文

我在Python3.8中有一个名为“stores.py”的文件。这个文件有一个名为“scan_transactions”的方法,它接受两个位置参数:“store”和“checkpoint”。该方法基本上通过使用正则表达式模式扫描PostgreSQL表中的存储事务。当代码到达事务表中该特定存储的最后一个事务id时,将使用并更新另一个表(检查点表),以指示任何给定存储的最新最大事务id

目前,我正在从一个预定义的字典(类似于下面的字典)传递这两个参数:

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”以编程方式将参数“-shop1”、““-shop2”转换为类似于上面的字典(它们各自的检查点作为值),并使用当前运行的相同循环处理所有存储吗


Tags: 文件方法store代码pyid参数字典
3条回答

我发现使用一个在,上拆分的结构来读取可能性列表是很方便的

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参数来重复它们(即,您没有存储选项名称)。或者,也许我对OptPass感到困惑,因为我现在主要使用Click

文档的nargs部分涵盖了这一点,因此看起来您也可以使用 store。没有非常清楚的例子。也就是说,对于用户来说,这需要更多的输入,所以我会选择位置

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}")

输出:

(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

替代解决方案:只需读取一个JSON配置文件,可能将参数设置为stdin的文件名或触发器

import json

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

相关问题 更多 >