如何将参数从命令行传递到 python 脚本以读取和更新 json 文件中存在的某些键的值

How do I pass arguments from command line to the python script to read and update values of certain keys present in a json file

我在 json 文件中有某些数据(比如 example.json),

example.json

data = {
     'name'   :  'Williams',
     'working':  False,
     'college':  ['NYU','SU','OU'],
     'NYU'    :  {
                  'student'  : True,
                  'professor': False,
                  'years'    : {
                                 'fresher'  : '1',
                                 'sophomore': '2',
                                 'final'    : '3'

                                }

                   }
   }

我想编写一个代码,其中我可以在命令行上给出参数,即假设如果脚本保存在文件 'script.py' 中,那么,

在终端中:如果我输入 *$ python3* script.py --get name --get NYU.student 然后它输出 name=Williams

NYU.student=True

如果我输入*$ python3* script.py' --set name=Tom --set NYU.student=False

然后,它将字典中的 name 和 NYU.student 键更新为 Tom 和 False,并在命令行上输出 NYU.student=TomNYU.student=False

我已经为 python 脚本尝试了以下代码(即 script.py)

script.py

import json
import pprint
import argparse


    if __name__== "__main__":
    parser = argparse.ArgumentParser()

    parser.add_argument("--get", help="first command")
    parser.add_argument("--set", help="second command")


    args=parser.parse_args()

    with open('example.json','r') as read_file:
        data=json.load(read_file)
    



    if args.set == None:
        key = ' '.join(args.get[:])
        path = key.split('.')
        now = data
        for k in path:
          if k in now:
            now = now[k]
          else:
            print('Error: Invalid Key')
        print(now)  
    elif args.get == Null:
        key, value = ' '.join(args.set[:]).split('=')
        path = key.split('.')
        now = data
        for k in path[:-1]:
            if k in now:
                now = now[k]
            else:
                print('Error: Invalid Key')
        now[path[-1]] = value



    with open('example.json','w') as write_file:    #To write the updated data back to the same file
            json.dump(data,write_file,indent=2)
    

但是,我的脚本没有按预期运行?请帮助我编写脚本

为了使用命令行传递参数,请使用 python3 中的 sys 模块。 sys 模块将命令行参数读取为字符串列表。列表中的第一个元素始终是文件名,后续元素是 arg1、arg2 ..... 等等。

希望下面的例子有助于理解sys模块的使用。

示例命令:

python filename.py 1 thisisargument2 4

对应代码

import sys

# Note that all the command line args will be treated as strings
# Thus type casting will be needed for proper usage

print(sys.argv[0])
print(sys.argv[1])
print(sys.argv[2])
print(sys.argv[3])    

对应输出

filename.py 
1 
thisisargument2 
4

在 Whosebug 上发布问题之前,请进行彻底的 google 搜索。

您的代码存在以下问题:

  1. 在第 23 行和第 35 行连接参数值时,您使用 space。这导致“错误键”值。删除 space 将解决问题。
key = ''.join(arg[:])
  1. 您将参数定义为仅传递一个值。不是多个。因此,即使您传递多个 --get--set 值,脚本也只会获得一个值。在第 9 行和第 10 行添加 action="append" 将解决问题。
parser.add_argument("--get", help="first command", action="append")
parser.add_argument("--set", help="second command", action="append")

完整代码:

import json
import pprint
import argparse


if __name__== "__main__":
    parser = argparse.ArgumentParser()

    parser.add_argument("--get", help="first command", action="append")
    parser.add_argument("--set", help="second command", action="append")


    args=parser.parse_args()
    try:
        with open('example.json','r') as read_file:
            data=json.load(read_file)
    except IOError:
        print("ERROR: File not found")
        exit()
    
    if args.set == None:
        for arg in args.get:
            
            key = ''.join(arg[:])
            
            path = key.split('.')
            now = data
            for k in path:
              if k in now:
                now = now[k]
              else:
                print('Error: Invalid Key')
            print(f"{arg} = {now}")  
    elif args.get == None:
        for arg in args.set:
            key, value = ''.join(arg[:]).split('=')
            
            path = key.split('.')
            now = data
            for k in path[:-1]:
                if k in now:
                    now = now[k]
                else:
                    print('Error: Invalid Key')
            print(f"{arg}")
            now[path[-1]] = value
            



    with open('example.json','w') as write_file:    #To write the updated data back to the same file
            json.dump(data,write_file,indent=2)
   

这里是题的get部分,希望你能继续做题的set部分。祝你好运

python test.py --get name NYU.student

import json
import pprint
import argparse

def match(data: dict, filter: str):
    current = data

    for f in filter.split("."):
        if f not in current:
            return False
        current = current[f]
    
    return current == True
    

if __name__== "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("--get", nargs="*", help="first command")

    args = parser.parse_args()

    with open('example.json','r') as f:
        data = json.loads(f.read())

    if args.get is not None and len(args.get) == 2:
        attr_name = args.get[0]
        if match(data, args.get[1]):
            print("{}={}".format(attr_name, data[attr_name]))