在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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/910771.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ESP8266 自定义固件烧录-Tcpsocket固件

一、固件介绍 固件为自定义开发的一个适配物联网项目的开源固件&#xff0c;支持网页配网、支持网页tcpsocket服务器配置、支持串口波特率设置。 方便、快捷、稳定&#xff01; 二、烧录说明 固件及工具打包下载地址&#xff1a; https://download.csdn.net/download/flyai…

I.MX6U 裸机开发3. GPIO操作控制LED灯

I.MX6U 裸机开发3. GPIO操作控制LED灯 一、创建项目目录及源文件1. 新建目录2. 远程开发环境3. 创建源文件 二、代码编写1. 打开时钟2. 配置端口复用功能为GPIO3. 配置端口电气属性4. 设置GPIO方向&#xff08;GDIR寄存器&#xff09;5. 输出6. 死循环等待 三、编译程序1. 整体…

「Mac畅玩鸿蒙与硬件19」鸿蒙UI组件篇9 - 自定义动画实现

自定义动画让开发者可以设计更加个性化和复杂的动画效果&#xff0c;适合表现独特的界面元素。鸿蒙提供了丰富的工具&#xff0c;支持通过自定义路径和时间控制来创建复杂的动画运动。本篇将带你学习如何通过自定义动画实现更多样化的效果。 关键词 自定义动画动画路径贝塞尔曲…

FLUX 推出 Ultra 和 Raw 模式,仅10秒生成2K高清图!

大家好&#xff0c;我是渔夫。 就在 2024年11月6日&#xff0c;BlackForestLabs 团队升级了他们最新的文生图模型 FLUX1.1 [pro]。 推出 Ultra 和 Raw 模式&#xff0c;仅10秒就能生成2K高清图片&#xff0c;速度非常惊人。 Ultra 模式&#xff1a;可生成超高分辨率图像&#x…

24/11/6 算法笔记 SVD

SVD&#xff0c;即奇异值分解&#xff08;Singular Value Decomposition&#xff09;&#xff0c;是线性代数中一种重要的矩阵分解方法。 定义 对于任何给定的 mnmn 的实数矩阵 AA&#xff08;其中 mm 是行数&#xff0c;nn 是列数&#xff09;&#xff0c;SVD分解可以表示为…

开发笔记 | 快速上手基于Dify等第三方大模型平台接口实现AI智能聊天

前置&#xff1a; 1.部署Dify&#xff0c;见官方教程及介绍https://docs.dify.ai/zh-hans&#xff0c;本文主要讲基于部署完之后的java实现的调用它的接口实现AI智能聊天&#xff0c;其他AI功能后续有用到再补充&#xff0c;没有就看缘分 2.什么是Dify&#xff1f;可以简单理解…

数据分析:转录组差异fgsea富集分析

文章目录 介绍加载R包数据链接导入数据数据预处理DE testing: 2BP vs no-BP比较limma-voomLoad steroid dataIn No-BP patientsIn 2BP patientsCompare gene expression vs bacterial mass其他系统信息介绍 转录组差异fgsea富集分析是一种基于基因集的富集分析方法,它关注的是…

查看网路信息-ifconfig命令

1.ifconfig缺点&#xff1a; 可以查看接口的网络类型&#xff1b;部分IP和掩码以及状态是否插线&#xff0c;看不到接口下的网关&#xff0c;DNS, 要想看到接口下多个IP,使用 ip addr show 命令 要想看网关&#xff0c;使用 ip route show 命令、route -n 命令 显示路由表内…

基于Spring Boot的中小型制造企业质量管理系统设计与实现,LW+源码+讲解

摘 要 信息数据从传统到当代&#xff0c;是一直在变革当中&#xff0c;突如其来的互联网让传统的信息管理看到了革命性的曙光&#xff0c;因为传统信息管理从时效性&#xff0c;还是安全性&#xff0c;还是可操作性等各个方面来讲&#xff0c;遇到了互联网时代才发现能补上自…

Java:多态的调用

1.什么是多态 允许不同类的对象对同一消息做不同的响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。&#xff08;发送消息就是函数调用&#xff09;。多态使用了一种动态绑定&#xff08;dynamic binding&#xff09;技术&#xff0c;指在执行期间判断所引用…

并查集算法详解

文章目录 并查集概念并查集的常见操作构建并查集合并并查集和查找 关于find函数 并查集概念 并查集&#xff08;Union-Find&#xff09;是一种树型的数据结构&#xff0c;用于处理一些不交集的合并及查询问题。其主要应用是判断两个元素是否在同一个集合中&#xff0c;以及合并…

Redis持久化机制——针对实习面试

目录 Redis持久化机制Redis为什么要有持久化机制&#xff1f;Redis持久化方式有哪些&#xff1f;AOF持久化工作原理是什么&#xff1f;有什么优缺点&#xff1f;AOF持久化工作原理AOF的优点AOF的缺点 RDB持久化工作原理是什么&#xff1f;有什么优缺点&#xff1f;RDB持久化工作…

【系统架构设计师(第2版)】七、系统架构设计基础知识

有效的软件体系结构及其明确的描述和设计&#xff0c;已成为软件工程领域中重要的主题。 *注&#xff1a;由于历史原因&#xff0c;研究者和工程人员对**Software Architecture&#xff08;简称SA&#xff09;*的翻译不尽相同&#xff0c;本文中软件“体系结构”和“架构”具有…

【NLP】使用 SpaCy、ollama 创建用于命名实体识别的合成数据集

命名实体识别 (NER) 是自然语言处理 (NLP) 中的一项重要任务&#xff0c;用于自动识别和分类文本中的实体&#xff0c;例如人物、位置、组织等。尽管它很重要&#xff0c;但手动注释大型数据集以进行 NER 既耗时又费钱。受本文 ( https://huggingface.co/blog/synthetic-data-s…

Google推出了AI驱动的学习工具“Learn About”

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

Vue3中使用LogicFlow实现简单流程图

实现结果 实现功能&#xff1a; 拖拽创建节点自定义节点/边自定义快捷键人员选择弹窗右侧动态配置组件配置项获取/回显必填项验证 自定义节点与拖拽创建节点 拖拽节点面板node-panel.vue <template><div class"node-panel"><divv-for"(item, k…

本地部署运行 HuggingFace Diffuser 大模型

最近需要篡改大模型验证篡改定位水印的泛化性&#xff0c;但是由于网络连接原因无法直接使用&#x1f917;s Diffusers library &#xff0c;在网上找到了以下本地部署的方法。 目录 下载模型&#xff0c;部署至服务器上 1&#xff09;huggingface官网下载 2&#xff09;gi…

Bert框架详解(下)

一、Bert模型网络结构 1、Add与Normalize Add&#xff1a;将前面的数据传到后面层&#xff0c;残差网络同理。 Normalize &#xff1a;归一化&#xff0c;与batch normalize同理。 2、outputs(shifted right) outputs&#xff08;shifted right&#xff09;&#xff1a;指在…

操作系统学习笔记-3.2虚拟内存

文章目录 虚拟内存请求分页管理方式页面置换算法最佳置换算法工作原理OPT 算法的示例最佳置换算法的优点和缺点 先进先出置换算法最近最久未使用时钟置换算法时钟置换算法的工作原理&#xff1a;算法的步骤&#xff1a; 改进型时钟置换算法改进型时钟置换算法的特点&#xff1a…

【数学】通用三阶矩阵特征向量的快速求法 超简单!!!

目录 三个定理1、3个特征值&#xff08;即根互不相等&#xff09;例题实践2、2个特征值&#xff08;即有一个双重根&#xff09;3、1个特征值&#xff08;即有一个三重根&#xff09;定理证明 三个定理 本定理适用于 所有三阶矩阵 的特征向量求法&#xff01; 1、3个特征值&…