我在Python 3.8中有一个名为";stores.py";这个文件有一个名为";scan_transactions";其采用2个位置自变量:";存储";以及";检查点";。该方法基本上是通过使用REGEX模式来扫描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解析器";以某种方式程序化地转换参数"-商店1""-shop2";插入到像上面这样的字典中(将它们各自的检查点作为值(,并使用我当前运行的相同循环处理所有存储?
注意,我认为您需要使用位置argparse参数来重复它们(即,您没有它们的--store选项名称(。或者我可能对optparse感到困惑,这些天主要使用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
我发现使用在,
上拆分的结构来读取的可能性列表很方便
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
替代解决方案:只需读取JSON配置文件,也许将参数设置为stdin
的文件名或触发器
import json
...
with open(path_config) as fh:
config = json.load(fh) # config is now a Python dict