超干!如何编写完美的Python命令行程序?

如何编写完美的Python命令行程序? 作为 Python 开发者,我们经常要编写命令行程序。比如在我的数据科学项目中,我要从命令行运行脚本来训练模型,以及计算算法的准确率等。 因此,更方便更易用的脚本能够很好地提高生产力,特别是在有多个开发者从事同一个项目的场合下。 因此,我建议你遵循以下四条规则: 尽可能提供默认参数值 所有错误情况必须处理(例如,参数缺失,类型错误,找不到文件) 所有参数和选项必须有文档 不是立即完成的任务应当显示进度条 举个简单的例子 我们把这些规则应用到一个具体的例子上。这个 阅读详情

这篇文章将教你如何编写完美的 Python 命令行程序,提高团队的生产力,让大家的工作更舒适。

作为 Python 开发者,我们经常要编写命令行程序。比如在我的数据科学项目中,我要从命令行运行脚本来训练模型,以及计算算法的准确率等。

因此,更方便更易用的脚本能够很好地提高生产力,特别是在有多个开发者从事同一个项目的场合下。

因此,我建议你遵循以下四条规则:

尽可能提供默认参数值

所有错误情况必须处理(例如,参数缺失,类型错误,找不到文件)

所有参数和选项必须有文档

不是立即完成的任务应当显示进度条

举个简单的例子

我们把这些规则应用到一个具体的例子上。这个脚本可以使用凯撒加密法加密和解密消息。

假设已经有个写好的 encrypt 函数(实现如下),我们需要创建一个简单的脚本,用来加密和解密消息。我们希望让用户通过命令行参数选择加密模式(默认)和解密模式,并选择一个秘钥(默认为 1)。

def encrypt(plaintext, key):
    cyphertext = ''
    for character in plaintext:
        if character.isalpha():
            number = ord(character)
            number += key
            if character.isupper():
                if number > ord('Z'):
                    number -= 26
                elif number < ord('A'):
                    number += 26
            elif character.islower():
                if number > ord('z'):
                    number -= 26
                elif number < ord('a'):
                    number += 26
            character = chr(number)
        cyphertext += character

    return cyphertext

我们的脚本需要做的第一件事就是获取命令行参数的值。当我搜索“python command line arguments”时,出现的第一个结果是关于sys.argv的,所以我们来试试这个方法……

“初学者”的方法

sys.argv 是个列表,包含用户在运行脚本时输入的所有参数(包括脚本名自身)。

例如,如果我输入:

> python caesar_script.py --key 23 --decrypt my secret message
pb vhfuhw phvvdjh

该列表将包含:

['caesar_script.py', '--key', '23', '--decrypt', 'my', 'secret', 'message'] 

因此只需遍历该参数列表,找到’–key’(或’-k’)以得到秘钥值,找到’–decrypt’以设置解密模式(实际上只需要使用秘钥的反转作为秘钥即可)。

最后我们的脚本大致如下:

import sys

from caesar_encryption import encrypt


def caesar():
    key = 1
    is_error = False

    for index, arg in enumerate(sys.argv):
        if arg in ['--key', '-k'] and len(sys.argv) > index + 1:
            key = int(sys.argv[index + 1])
            del sys.argv[index]
            del sys.argv[index]
            break

    for index, arg in enumerate(sys.argv):
        if arg in ['--encrypt', '-e']:
            del sys.argv[index]
            break
        if arg in ['--decrypt', '-d']:
            key = -key
            del sys.argv[index]
            break

    if len(sys.argv) == 1:
        is_error = True
    else:
        for arg in sys.argv:
            if arg.startswith('-'):
                is_error = True

    if is_error:
        print(f'Usage: python {sys.argv[0]} [ --key <key> ] [ --encrypt|decrypt ] <text>')
    else:
        print(encrypt(' '.join(sys.argv[1:]), key))

if __name__ == '__main__':
    caesar()

这个脚本遵循了一些我们前面推荐的规则:

  • 支持默认秘钥和默认模式
  • 基本的错误处理(没有提供输入文本的情况,以及提供了无法识别的参数的情况)
  • 出错时或者不带任何参数调用脚本时会显示文档:
> python caesar_script_using_sys_argv.py
Usage: python caesar.py [ --key <key> ] [ --encrypt|decrypt ] <text>

但是,这个凯撒加密法脚本太长了(39 行,其中甚至还没包括加密代码本身),而且很难读懂。

解析命令行参数应该还有更好的办法……

试试 argparse?

argparse 是 Python 用来解析命令行参数的标准库。

我们来看看用 argparse 怎样编写凯撒加密的脚本:

import argparse

from caesar_encryption import encrypt


def caesar():
    parser = argparse.ArgumentParser()
    group = parser.add_mutually_exclusive_group()
    group.add_argument('-e', '--encrypt', action='store_true')
    group.add_argument('-d', '--decrypt', action='store_true')
    parser.add_argument('text', nargs='*')
    parser.add_argument('-k', '--key', type=int, default=1)
    args = parser.parse_args()

    text_string = ' '.join(args.text)
    key = args.key
    if args.decrypt:
        key = -key
    cyphertext = encrypt(text_string, key)
    print(cyphertext)

if __name__ == '__main__':
    caesar()

这段代码也遵循了上述规则,而且与前面的手工编写的脚本相比,可以提供更准确的文档,以及更具有交互性的错误处理:

> python caesar_script_using_argparse.py --encode My message

usage: caesar_script_using_argparse.py [-h] [-e | -d] [-k KEY] [text [text ...]]
caesar_script_using_argparse.py: error: unrecognized arguments: --encode
> python caesar_script_using_argparse.py --help

usage: caesar_script_using_argparse.py [-h] [-e | -d] [-k KEY] [text [text ...]]
positional arguments:
  text
optional arguments:
  -h, --help         show this help message and exit
  -e, --encrypt
  -d, --decrypt
  -k KEY, --key KEY

但是,仔细看了这段代码后,我发现(虽然有点主观)函数开头的几行(从7行到13行)定义了参数,但定义方式并不太优雅:它太臃肿了,而且完全是程式化的。应该有更描述性、更简洁的方法。

click 能做得更好!

幸运的是,有个 Python 库能提供与 argparse 同样的功能(甚至还能提供更多),它的代码风格更优雅。这个库的名字叫 click。

这里是凯撒加密脚本的第三版,使用了 click:

import click

from caesar_encryption import encrypt

@click.command()
@click.argument('text', nargs=-1)
@click.option('--decrypt/--encrypt', '-d/-e')
@click.option('--key', '-k', default=1)
def caesar(text, decrypt, key):
    text_string = ' '.join(text)
    if decrypt:
        key = -key
    cyphertext = encrypt(text_string, key)
    click.echo(cyphertext)

if __name__ == '__main__':
    caesar()

注意现在参数和选项都在修饰器里定义,定义好的参数直接作为函数参数提供。

我来解释一下上面代码中的一些地方:

  • 脚本参数定义中的nargs参数指定了该参数期待的单词的数目(一个用引号括起来的字符串算一个单词)。默认值是1。这里nargs=-1允许接收任意数目的单词。
  • –encrypt/–decrypt这种写法可以定义完全互斥的选项(类似于argparse中的add_mutually_exclusive_group函数),它将产生一个布尔型参数。
  • click.echo是该库提供的一个工具函数,它的功能与print相同,但兼容Python 2和Python 3,还有一些其他功能(如处理颜色等)。

添加一些隐秘性

这个脚本的参数(被加密的消息)应当是最高机密。而我们却要求用户直接在终端里输入文本,使得这些文本被记录在命令历史中,这不是很讽刺吗?

解决方法之一就是使用隐藏的提示。或者可以从输入文件中读取文本,对于较长的文本来说更实际一些。或者可以干脆让用户选择。

输出也一样:用户可以保存到文件中,也可以输出到终端。这样就得到了凯撒脚本的最后一个版本:

import click

from caesar_encryption import encrypt

@click.command()
@click.option(
    '--input_file',
    type=click.File('r'),
    help='File in which there is the text you want to encrypt/decrypt.'
         'If not provided, a prompt will allow you to type the input text.',
)
@click.option(
    '--output_file',
    type=click.File('w'),
    help='File in which the encrypted / decrypted text will be written.'
         'If not provided, the output text will just be printed.',
)
@click.option(
    '--decrypt/--encrypt',
    '-d/-e',
    help='Whether you want to encrypt the input text or decrypt it.'
)
@click.option(
    '--key',
    '-k',
    default=1,
    help='The numeric key to use for the caesar encryption / decryption.'
)
def caesar(input_file, output_file, decrypt, key):
    if input_file:
        text = input_file.read()
    else:
        text = click.prompt('Enter a text', hide_input=not decrypt)
    if decrypt:
        key = -key
    cyphertext = encrypt(text, key)
    if output_file:
        output_file.write(cyphertext)
    else:
        click.echo(cyphertext)

if __name__ == '__main__':
    caesar()

这个版本有什么新东西吗?

  • 首先,注意到我给每个参数选项都加了个help参数。由于脚本变得复杂了,help参数可以给脚本的行为添加一些文档。运行结果如下:
> python caesar_script_v2.py --help
Usage: caesar_script_v2.py [OPTIONS]
Options:
  --input_file FILENAME          File in which there is the text you want to encrypt/decrypt. If not provided, a prompt will allow you to type the input text.
  --output_file FILENAME         File in which the encrypted/decrypted text will be written. If not provided, the output text will just be printed.
  -d, --decrypt / -e, --encrypt  Whether you want to encrypt the input text or decrypt it.
  -k, --key INTEGER              The numeric key to use for the caesar encryption / decryption.
  --help                         Show this message and exit.
  • 两个新的参数:input_file 和 output_file,类型均为 click.File。该库能够用正确的模式打开文件,处理可能的错误,再执行函数。例如:
> python caesar_script_v2.py --decrypt --input_file wrong_file.txt
Usage: caesar_script_v2.py [OPTIONS]
Error: Invalid value for "--input_file": Could not open file: wrong_file.txt: No such file or directory
  • 正像help文本中解释的那样,如果没有提供input_file,就使用click.promp让用户直接在提示符下输入文本,在加密模式下这些文本是隐藏的。如下所示:
> python caesar_script_v2.py --encrypt --key 2
Enter a text: **************
yyy.ukectc.eqo

学习资源推荐
除了上述分享,学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!

包括:Python激活码+安装包、Python web开发,Python爬虫,Python数据分析,人工智能、自动化办公等学习教程。带你从零基础系统性的学好Python!

👉Python所有方向的学习路线👈

Python所有方向路线就是把Python常用的技术点做整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。(全套教程文末领取)

在这里插入图片描述
👉Python学习视频600合集👈

观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。

在这里插入图片描述

温馨提示:篇幅有限,已打包文件夹,获取方式在:文末

👉Python70个实战练手案例&源码👈

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

在这里插入图片描述

👉Python大厂面试资料👈

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

在这里插入图片描述

在这里插入图片描述

👉Python副业兼职路线&方法👈

学好 Python 不论是就业还是做副业赚钱都不错,但要学会兼职接单还是要有一个学习规划。

在这里插入图片描述

👉 这份完整版的Python全套学习资料已经上传,朋友们如果需要可以V扫描下方二维码联系领取
【保证100%免费
】

使用Click库创建强大的Python命令行程序 命令行程序是日常开发中常见的工具,它们可以帮助我们执行各种任务,从简单的文件操作到复杂的数据处理。命令行应用程序在日常开发中非常常见,它们能够帮助我们完成各种任务,从简单的文件操作到复杂的数据处理。除了基本的命令行参数之外,Click还提供了许多其他功能来增强我们的命令行应用程序。除了基本的命令行参数之外,Click还提供了许多其他功能来增强我们的命令行程序。现在,我们可以在命令行中运行我们的应用程序,并尝试不同的选项和参数。现在,我们可以在命令行中运行我们的程序并尝试不同的选项和参数。 阅读详情

相关推荐

Fluent 中多相流模型全面解析

3.颗粒或液滴在连续相中的运动:若关注颗粒或液滴在连续相中的运动轨迹、分布规律以及与连续相的相互作用,如喷雾干燥、气力输送等过程,Eulerian-Lagrangian 模型则是最佳选择。Eulerian-Eulerian 模型可以准确模拟气体在固体颗粒中的流动情况,包括颗粒的流化状态、气体与颗粒之间的传热传质过程,为气固流化床的优化设计和操作提供依据。通过该模型,可以了解混合器内不同位置的混合程度、颗粒的运动轨迹以及液固相间的相互作用,从而改进混合器的结构和操作条件,提高混合效率。

khhdp的博客 3086

如何编写完美的 Python 命令行程序?

这篇文章将教你如何编写完美的 Python 命令行程序,提高团队的生产力,让大家的工作更舒适。作者 |Yannick Wolff译者 |弯月责编 | 屠敏出品 |C...

优快云资讯 2788

库卡C4控制柜首次上电

本文详细介绍了如何使新购的库卡机器人(以KRC4为例)达到正常运行状态。首先,必须正确连接机器人尾部和控制柜底部的各种线缆,包括动力线缆、编码器线、SmartPad线和安全回路线缆等。特别强调,电源线和蓄电池线的正确连接至关重要,避免硬插以防损坏。此外,机器人与控制柜之间需连接地线以防止漏电。文章还提到,开机前需检查电机保护器开关,并确保所有线路连接正确。开机后,需提升用户权限至安全维护员级别,通过系统配置激活安全相关通讯参数。最后,文章详细解释了X11安全回路的接线方式,强调双通道信号的重要性,并提醒不同

2202_75959322的博客 1838

超干!如何编写完美的 Python 命令行程序?

但是,仔细看了这段代码后,我发现(虽然有点主观)函数开头的几行(从7行到13行)定义了参数,但定义方式并不太优雅:它太臃肿了,而且完全是程式化的。正像help文本中解释的那样,如果没有提供input_file,就使用click.promp让用户直接在提示符下输入文本,在加密模式下这些文本是隐藏的。脚本参数定义中的nargs参数指定了该参数期待的单词的数目(一个用引号括起来的字符串算一个单词)。幸运的是,有个 Python 库能提供与 argparse 同样的功能(甚至还能提供更多),它的代码风格更优雅。

Python宋宋的专栏 433

标准化降水指数介绍

Mckee et al.(1993)认为降水量的减少是导致干旱的主要因素,其他气候因子一般变化较小,对干旱产生的影响不大,因此SPI使用降水量作为唯一参数。SPI能较好表达因降水量的大小反映干旱状况,操作简单,所需资料仅为降水量,同时该干旱指数在各个地区和各个时段都具有良好的计算稳定性,是继PDSI之后另一种被广泛应用的干旱指数。𝐻(𝑥)是Γ分布求得的概率,并当𝐻(𝑥)>0.5时,S=1;式中,𝛼是形状参数,𝛽是尺度参数,𝑥是当月降水量,𝛤(𝛼)是Gamma函数,用极大似然估计法计算最佳的𝛼和𝛽,即。

weixin_44259522的博客 2857

储能电站 BMS 与车载动力电池 BMS 核心差异:工况、保护策略、控制逻辑对比

储能电站BMS与车载动力电池BMS虽同名,实为针对不同赛道量身定制的产品。简单地将车载BMS方案套用于储能,或将储能BMS思路用于车载,都可能带来性能、安全或成本上的严重问题。在选择和设计BMS时,必须回归其应用场景的本质需求储能BMS是**“资产管理者”**,精打细算,追求在长达十余年的服役期内稳定、高效地创造收益。车载BMS是**“性能与安全卫士”**,反应敏捷,确保在车辆全生命周期内动力澎湃且万无一失。

小帽子的博客 423

python怎么用命令行程序_Python写CLI命令行程序

使用Python写命令行程序,以argparse是基础,但是有两个更好的工具可以选择,click和oslo.configclickclick可以用于简单的命令行程序,下面是我写的一个demo$ cd click-demo$ python setup.py install$ clickctlUsage: clickctl [OPTIONS] COMMAND [ARGS]...Click Demo C...

weixin_39867066的博客 331

编写完美的python命令行程序,怎地不令人向往?

前言 我们作为一个python爱好者,我们常常要编写命令行程序,因此,更容易使用的脚本可以提高生产力,特别是当多个开发人员在同一个项目上工作时。 因此,我建议你遵循以下四条规则: 尽可能提供默认参数值 所有错误情况必须处理(例如,参数缺失,类型错误,找不到文件) 所有参数和选项必须有文档 不是立即完成的任务应当显示进度条 举个简单的例子 我们把这些规则应用到一个具体的例子上。这个脚本可以使用凯撒加...

qq_39363022的博客 467

交流伺服电机绝对式位置控制实战指南

伺服电机控制是工业自动化的核心技术之一,其核心原理是通过闭环反馈实现精确位置控制。绝对值编码器作为关键传感器,能提供单圈内的绝对位置信息,避免了增量式编码器的累计误差问题。在工程实践中,电子齿轮比配置、位置环PID调节等技术直接影响系统动态性能。本文以包装机械为典型场景,详细解析了从硬件选型到参数整定的全流程实现方案,特别是针对单圈绝对值编码器初始化和限位保护等易错环节,给出了经过验证的解决方案。通过合理设置17位编码器的电子齿轮比和优化运动控制算法,最终实现了±0.05°的高精度定位。

weixin_42531588的博客 281

【UVM实战】第七章:UVM中的寄存器模型(1)寄存器模型简介

寄存器模型简介~

悟已往之不谏 知来者之可追 2070

python编出来的程序怎么运用_教你如何编写完美的Python命令行程序

这篇文章将教你如何编写完美的Python命令行程序,提高团队的生产力,让大家的工作更舒适。作者| Yannick Wolff作为Python开发者,我们经常要编写命令行程序。比如在我的数据科学项目中,我要从命令行运行脚本来训练模型,以及计算算法的准确率等。因此,更方便更易用的脚本能够很好地提高生产力,特别是在有多个开发者从事同一个项目的场合下。因此,我建议你遵循以下四条规则:尽可能提供默认参数值所...

weixin_39985279的博客 136

2026华为OD面试题084:贪心的商人

商人经营一家店铺,有 `number` 种商品。由于仓库限制,每件商品的最大持有数量是 `item[index]`。 每种商品每天有一个价格 `item_price[item_index][day]`。通过对商品买进和卖出获取利润,请给出商人在 `days` 天内能获取到的最大利润。 注:同一件商品可以反复买进和卖出。 输入描述: - 第一行输入商品数量 `number` - 第二行输入商人售货天数 `days` - 第三行输入 `number` 个整数,表示每件商品的最大持有数量 `item[in

琅嬛福地 274

使用click创建完美的Python命令行程序

Python程序员的主要工作是写命令行程序,即直接在终端运行的脚本。 随着项目规模增长,我们希望创建有效的命令行接口,通过提供不同的参数,解决不同的问题,而不是每次都修改源代码。 Click库是一个非常高效的命令行工具,能够帮助我们快速创建完美的命令行接口,小编认为这是每个Python程序员都应该掌握的工具。 原文出处:Medium 作者:Yannick 原文标题:perfect-command-line-interfaces-python 作为Python开发人员,我们经常编写命令行程序。例如,在.

量化炼金 | CodeAlchemy 701

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

python 写命令行_使用Python轻松写出漂亮的命令行程序

使用Python轻松写出漂亮的命令行程序

weixin_39710396的博客 400

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Python教程:如何编写完美的Python命令行程序?

作为 Python 开发者,我们经常要编写命令行程序。比如在我的数据科学项目中,我要从命令行运行脚本来训练模型,以及计算算法的准确率等。 因此,更方便更易用的脚本能够很好地提高生产力,特别是在有多个开发者从事同一个项目的场合下。 因此,我建议你遵循以下四条规则: 尽可能提供默认参数值 所有错误情况必须处理(例如,参数缺失,类型错误,找不到文件) 所有参数和选项必须有文档 不是立即完成的任务应当显示进度条 举个简单的例子 我们把这些规则应用到一个具体的例子上。这个

z099164的博客 1338

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

干货 | 使用Python轻松写出漂亮的命令行程序

点击上方“中兴开发者社区”,关注我们每天读一篇一线开发者原创好文作者简介作者王辉,热爱编程的程序员一枚,喜欢研究技术,乐于分享。致力于TDD、Clean Code、DDD等实践的落实实施,是软件设计和软件架构方法的积极学习者和实践者。诞生之初用来作为配置管理语言的Python,现在已经成为最流行的编程语言之一,尤其是随着AI应用的兴起,变得无处不在。Python中的getopt,optparse模

中兴开发者社区 2282

每日一课 | 如何编写完美的Python命令行程序?

作者 |Yannick Wolff译者 |弯月作为 Python 开发者,我们经常要编写命令行程序。比如在我的数据科学项目中,我要从命令行运行脚本来训练模型,以及计算算法的准确率等。...

sinat_32849897的博客 429

在python中运行程序的命令是_在python中执行命令行程序

本问题已经有最佳答案,请猛点这里访问。Possible Duplicate:Calling an external command in Python我正在构建一个Web应用程序,它将处理(pad、mix、merge等)声音文件,我发现sox正是我想要的。SOX是一个Linux命令行程序,我对让PythonWeb应用在我的服务器上按请求启动新的SOX进程感到有点不舒服。例子:import osos...

weixin_35441226的博客 1043
上一篇: Python实现外观模式、桥接模式、组合模式和享元模式
下一篇: 推荐七个Python效率工具!
Python干货分享
博客等级 码龄3年 607粉丝 37原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值