python中解析命令行参数的示例详解

 更新时间:2024年11月08日 08:48:19   作者:仙草哥哥  
这篇文章主要为大家详细介绍了python中命令行参数的解析,并做一个命令行程序,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下

命令行参数

加密程序

考虑这样一个加密程序,其中一个功能,是对一段字符串进行base64加密,另一个功能,是对一段base64字符串解密:

import base64
 
def encrypt_to_base64(input_string):
    byte_data = input_string.encode("utf-8")
    base64_encoded = base64.b64encode(byte_data)
    return base64_encoded.decode("utf-8")
 
def decrypt_from_base64(base64_string):
    byte_data = base64_string.encode("utf-8")
    decoded_data = base64.b64decode(byte_data)
    return decoded_data.decode("utf-8")
 
encrypt_to_base64("sagegrass")
decrypt_from_base64("c2FnZWdyYXNz")

对于这样一个功能,如果我希望通过命令行调用,然后快速得到结果,可能是像这样的:

# 设置-e选项,进行加密
python base64_encrypt.py -e "sagegrass"
 
# 设置-d选项,进行解密
python base64_encrypt.py -d "c2FnZWdyYXNz"

那么,该怎么做到呢?

sys.argv

命令行参数以列表的形式,保存于sys模块的argv属性中,具体来说

import sys
 
print(sys.argv)
 
# 对于python base64_encrypt.py -e "123456",结果为:['base64_encrypt.py', '-e', 'sagegrass']
# 对于python base64_encrypt.py -d "MTIzNDU2",结果为:['base64_encrypt.py', '-d', 'c2FnZWdyYXNz']

处理命令行参数

因此,根据sys.argv的返回结果,我们可以假设,如果用户的使用方法正确,那么,我们可以:

import base64
import sys
 
def encrypt_to_base64(input_string):
    byte_data = input_string.encode("utf-8")
    base64_encoded = base64.b64encode(byte_data)
    return base64_encoded.decode("utf-8")
 
def decrypt_from_base64(base64_string):
    byte_data = base64_string.encode("utf-8")
    decoded_data = base64.b64decode(byte_data)
    return decoded_data.decode("utf-8")
 
 
if len(sys.argv) >= 3:
    if sys.argv[1] == "-e":
        print(encrypt_to_base64(sys.argv[2]))
    elif sys.argv[1] == "-d":
        print(decrypt_from_base64(sys.argv[2]))

此时,我们程序已经可以正确处理-e以及-d的参数了。

复杂命令行参数

计算器案例

考虑这样一个计算器程序,允许接受两个参数,并且选择一个操作,进行加,减,乘,除的操作。

但是,也可以允许只接受一个参数,并且选择进行平方,或者开根号的操作。

同时,也应该允许用户可以先提供数字,或者后提供数字。

# 实现一个加法操作
python calculator.py 520 0.1314 --operation add
python calculator.py -o add 520 0.1314 
 
# 实现一个平方操作
python calculator.py -o square 5

因为操作较为复杂,用户可能搞不清楚,所以同样应该提供一份帮助说明。

python calculator.py -h

那么,在这种情况下,如果还是使用sys.argv,并且在整个列表中,去解析命令行参数,会非常麻烦。因此,需要更好的工具,去处理这个问题。

argparse

argparse是一个更好的工具,可以处理更加复杂的命令行参数。

创建ArgumentParser对象

parser = argparse.ArgumentParser(description="base64加解密")

添加位置参数

parser.add_argument("text", type=str, help="用于加解密的一段文本")

添加操作符

parser.add_argument("-e", "--encrypt", action="store_true", help="对文本进行base64加密")
parser.add_argument("-d", "--decrypt", action="store_true", help="对文本进行base64解密")

解析参数

args = parser.parse_args()
if args.encrypt:
    print(encrypt_to_base64(args.text))
elif args.decrypt:
    print(decrypt_from_base64(args.text))
argparse处理base64加解密
import base64
import argparse
 
def encrypt_to_base64(input_string):
    byte_data = input_string.encode("utf-8")
    base64_encoded = base64.b64encode(byte_data)
    return base64_encoded.decode("utf-8")
 
def decrypt_from_base64(base64_string):
    byte_data = base64_string.encode("utf-8")
    decoded_data = base64.b64decode(byte_data)
    return decoded_data.decode("utf-8")
 
parser = argparse.ArgumentParser(description="base64加解密")
 
parser.add_argument("text", type=str, help="待加解密的文本")
 
parser.add_argument("-e", "--encrypt", action="store_true", help="对文本进行base64加密")
parser.add_argument("-d", "--decrypt", action="store_true", help="对文本进行base64解密")
 
args = parser.parse_args()
if args.encrypt:
    print(encrypt_to_base64(args.text))
elif args.decrypt:
    print(decrypt_from_base64(args.text))

argparse处理计算器

import argparse
import math
 
parser = argparse.ArgumentParser(description="一个命令行的计算器")
 
parser.add_argument("num1", type=float, help="第一个数字")
parser.add_argument("num2", type=float, nargs='?', default=None, help="第二个数字(平方和开根号操作无需提供)")
parser.add_argument("-o", "--operation", choices=["add", "sub", "mul", "div", "square", "sqrt"], default="add", help="选择操作:add(加),sub(减),mul(乘),div(除),square(平方),sqrt(开根号)")
 
 
args = parser.parse_args()
 
if args.operation in ["add", "sub", "mul", "div"]:
    if args.num2 is None:
        parser.error(f"操作'{args.operation}'需要提供两个数字。")
elif args.operation in ["square", "sqrt"]:
    if args.num2 is not None:
        parser.error(f"操作'{args.operation}'只需要提供一个数字。")
 
 
if args.operation == "add":
    result = args.num1 + args.num2
elif args.operation == "sub":
    result = args.num1 - args.num2
elif args.operation == "mul":
    result = args.num1 * args.num2
elif args.operation == "div":
    if args.num2 == 0:
        result = "除数不能为零!"
    else:
        result = args.num1 / args.num2
elif args.operation == "square":
    result = args.num1 ** 2
elif args.operation == "sqrt":
    if args.num1 < 0:
        result = "不能对负数开平方根!"
    else:
        result = math.sqrt(args.num1)
else:
    result = None
 
if result is not None:
    print(f"结果: {result}")

在这种情况下,使用-h查看帮助的时候,就会发现,已经自动生成了一份简洁的帮助信息。

安装为全局命令

全局命令

我们可能经常观察到这样一种情况,在使用他人的第三方库的时候,可以使用命令,例如,lunar-find 春节 2025

而对比我们的命令行程序,则必须要按照python xxx的形式使用,而且必须找到对应的py文件,这并不方便,那么该可以让我们也使用全局命令呢?

my-lunar-find

因为原本的lunar-find输出格式不够灵活,因此,我们对其进行简单的重写,以满足可以输出任意格式的时间。

关于原本的lunar-find工具,如果你并不了解,可以看看这篇文章,lunarcalendar的使用

import argparse
 
from lunarcalendar.festival import festivals
from lunarcalendar.solarterm import solarterms
from itertools import chain
from datetime import date
 
def main():
    parser = argparse.ArgumentParser(description="自行创建的lunar-find,修改了原本的日期格式")
 
    parser.add_argument("fs_or_st", type=str, help="需要查找的节日或节气")
    parser.add_argument("year", type=int, help="年份")
    
    parser.add_argument("-f", "--format", default="%Y年%m月%d日", help="按照需要的格式重新格式化,%Y为年,%m为月,%d为日")
    
    args = parser.parse_args()
    
    for day in chain(festivals, solarterms):
        if day.get_lang("zh") == args.fs_or_st:
            formatted_time = day(args.year).strftime(args.format)
            print(formatted_time)
            
    
if __name__ == "__main__":
    main()

此时,可以通过提供--format,来按照需要格式化时间。

python my_lunar_find.py 春节 2025  # 输出:2025年01月29日
python my_lunar_find.py 春节 2025 --format %Y/%m/%d  # 输出:2025/01/29
python my_lunar_find.py 春节 2025 --format %Y-%m-%d  # 输出:2025-01-29

安装

编写一份setup.py

from setuptools import setup
 
setup(
    name="my_lunar_find",
    version="1.0",
    py_modules=["my_lunar_find"],
    entry_points={
        "console_scripts": [
            "my-lunar-find = my_lunar_find:main",
        ],
    },
)

安装:pip install .

注意:其中的.代表当前路径,因此需要在包含setup.py的目录下运行。

此时,是安装了一个我们自己的模块,my-lunar-find==1.0

调用命令:my-lunar-find 春节 2025

到此这篇关于python中解析命令行参数的示例详解的文章就介绍到这了,更多相关python解析命令行参数内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Python实现提取XML内容并保存到Excel中的方法

    Python实现提取XML内容并保存到Excel中的方法

    这篇文章主要介绍了Python实现提取XML内容并保存到Excel中的方法,涉及Python针对xml文件的读取、解析以及Excel文件的写入、保存等相关操作技巧,需要的朋友可以参考下
    2018-09-09
  • 使用python构建WebSocket客户端的教程详解

    使用python构建WebSocket客户端的教程详解

    WebSocket是一种在客户端和服务器之间实现双向通信的协议,常用于实时聊天、实时数据更新等场景,Python提供了许多库来实现 WebSocket客户端,本教程将介绍如何使用Python构建WebSocket客户端,文中通过代码示例给大家介绍的非常详细,需要的朋友可以参考下
    2023-12-12
  • MATLAB 全景图切割及盒图显示的实现步骤

    MATLAB 全景图切割及盒图显示的实现步骤

    本文给大家分两部分介绍,第一部分通过图文的形式给大家介绍了全景图切割的代码,第二部分给大家介绍了盒图展示效果的实现代码,对MATLAB 全景图切割相关知识感兴趣的朋友,跟随小编一起看看吧
    2021-05-05
  • python实现k-means聚类算法

    python实现k-means聚类算法

    这篇文章主要为大家详细介绍了python实现k-means聚类算法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-02-02
  • 使用Django Form解决表单数据无法动态刷新的两种方法

    使用Django Form解决表单数据无法动态刷新的两种方法

    这篇文章主要介绍了使用Django Form解决表单数据无法动态刷新的两种方法,需要的朋友可以参考下
    2017-07-07
  • python 中字典嵌套列表的方法

    python 中字典嵌套列表的方法

    今天小编就为大家分享一篇python 中字典嵌套列表的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-07-07
  • Python Pandas库简介及一些常见用法总结

    Python Pandas库简介及一些常见用法总结

    Pandas库是Python的免费、开源的第三方库,Pandas是Python数据分析必不可少的工具之一,这篇文章主要介绍了Python Pandas库简介及一些常见用法的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2025-07-07
  • python 中 lxml 的 etree 标签解析

    python 中 lxml 的 etree 标签解析

    这篇文章主要介绍了python 中lxml的etree 标签解析,文章围绕主题展开详细内容,需要的小伙伴可以参考一下,希望对你的学习或工作有所帮助
    2022-04-04
  • Gauss-Seidel迭代算法的Python实现详解

    Gauss-Seidel迭代算法的Python实现详解

    这篇文章主要介绍了Gauss-Seidel迭代算法的Python实现详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-06-06
  • 详解Python单元测试的两种写法

    详解Python单元测试的两种写法

    python的两个单元测试包分别是 doctest 和 unittest,这两个包的使用起来各有长处,适用于不同的场景,这篇文章主要介绍了Python单元测试的两种写法,需要的朋友可以参考下
    2022-07-07

最新评论