分享

使用命令行界面运行Python脚本

 hercules028 2022-03-09

excelperfect

标签:Python,argparse

本文将讲解如何使用带有argparse库的命令行界面运行Python脚本。命令行界面(CLI)允许我们通过在Shell(如果使用的是Windows,则为命令提示符)中键入命令来执行程序。我们可以在命令行上键入不同的参数并将这些参数传递到脚本中,而不是每次运行脚本时都更改.py文件中的代码。因此,使用CLI是非常灵活和方便的,而且,从黑屏启动程序会让你更酷,更像一个真正的程序员。

之前,我们在《使用Python拆分和合并PDF文件》中实现了PDF的拆分与合并,这里将在此基础上,添加一个命令行界面。我们还将稍微调整代码,定义三个变量,而不是硬编码程序中的所有值:PDF源文件、要提取的页面,以及最终生成的PDF,此设置将允许我们在任何PDF文件上使用该程序。

步骤1:下载并导入所需的库

PDF拆分与合并工具需要PyPDF4库,如果尚未安装,则安装它。

pip install PyPDF4

要使用的其他一些Python库是标准库,不需要进一步安装。

import argparse

from PyPDF4 import PdfFileReader,PdfFileWriter

import os, sys

步骤2:程序结构

要使用命令行界面运行Python脚本,Python程序中需要两个函数:main()split_merge_pdf()

main()函数负责从我们这里获取输入;split_merge_pdf()负责拆分和合并PDF文件,这是我们之前已开发的代码。其结构如下图所示。

Image

1CLI拆分与合并PDF工具程序结构

步骤3PDF拆分与合并函数

让我们首先将之前的代码转换为一个函数,该函数包含三个参数:输入文件、输出文件和页面。该函数将读取输入文件,提取所需页面,然后将这些页面保存到新的PDF文件中。注意,这里是如何使用类型暗示的,input_file(输入文件)和output_file(输出文件)都是string(字符串),pages(页面)是list(列表)。

def split_merge_pdf(input_file:str =None, output_file:str = None, pages:list = None):

   pdf = PdfFileReader(input_file)

   pdf_writer = PdfFileWriter()

   pages = [i-1 for i in pages]

   for p in pages:

        pdf_writer.addPage(pdf.getPage(p))

   with open(output_file, 'wb') as f:

        pdf_writer.write(f)

很简单!下面进入有趣的部分,我们希望在运行程序时从命令行传递这三个变量。

步骤4:从命令行解析参数

从命令行解析参数的最简单方法是使用sys.argv,它是传递给Python脚本的命令行参数列表。让我们看看如何通过在命令行中运行以下简单脚本来使用sys.argv

import sys

print(type(sys.argv))

print(len(sys.argv))

for i in sys.argv:

   print(i)

将上述代码保存到.py文件中。打开命令提示符(单击Windows中的搜索栏,然后键入“CMD”,回车),转到保存.py文件的文件夹。这里将文件保存为“sys_argv.py”,但你可以将其命名为任何名称,该文件保持在D盘根目录下。

导航到文件所在的目录,在命令提示符中键入以下命令:

sys_argv.py hello world 1,2,3

这将执行sys_argv.py,并将在“sys_argv.py”之后键入的任何内容作为参数传递到程序中。在我们的小程序中,打印:sys.argv的数据类型、长度以及其中的元素,结果如下图2所示。

Image

2

好了,现在我们已经了解了将命令行输入传递到Python脚本中的基础知识。注意,在CLI中只使用sys.argv是完全可以的。

步骤5:介绍argparse

argparse是一个标准的Python库,因此不需要专门安装它。我们可以定义程序需要的参数,argparse将找出如何从sys.argv解析这些参数。该库还自动生成帮助和用法消息。

首先,我们实例化ArgumentParser()对象。

然后,我们使用.add_argument()向解析器添加参数。在下面的示例中:

  • --input”是参数的名称。

  • type=file_path是命令行参数应转换为的类型。我们可以自定义并将参数转换为任何内容。注意,原始解析参数将始终是string(字符串)。

  • help是对参数作用的简短描述。

记住,split_merge_pdf()函数有三个参数,可以将它们全部添加到解析器对象中。

最后,我们将所有解析的参数赋值到一个名为args的变量中,可以通过调用args.inputargs.outputargs.pages来访问每个参数。

def main():

   parser = argparse.ArgumentParser()

   parser.add_argument('--input', type=file_path,default=None,

                        help='什么是输入PDF文件的路径?')

   parser.add_argument('--output', type=file_path,default=None,

                      help='什么是输出PDF文件的路径?')

   parser.add_argument('--pages', type=pages, default=None,

                       help='你想要提取哪些页?')

   args = parser.parse_args()

现在,我们来讨论type=file_pathtype=pages。我们知道解析后的参数将始终是字符串。

对于(Windows)计算机上的文件路径,由于有反斜杠/Python不喜欢未处理的文件路径;对于页面,整数列表[1,2,3]比字符串“1,2,3”更有意义,所以我们必须处理这些参数的格式。

基本上,对于file_path,我们将其转换为原始字符串,以便Python能够理解它。对于pages,我们将”1,2,3”字符串转换为整数列表。

def file_path(path):

   return rf'{path}'

def pages(pages):

   return [int(i) for i in pages.split(',')]

放在一起

现在,已经有了我们需要的所有部件,是时候把它们组装起来了。下面是完整的代码,将其保存为“pdf_cli_eg.py”,可以随意将代码另存为任何名称,只需在命令行上执行程序时键入正确的名称即可。

import argparse

from PyPDF4 import PdfFileReader,PdfFileWriter

import os, sys

def split_merge_pdf(input_file:str =None, output_file:str = None, pages:list = None):

   pdf = PdfFileReader(input_file)

   pdf_writer = PdfFileWriter()

   pages = [i-1 for i in pages]

   for p in pages:

        pdf_writer.addPage(pdf.getPage(p))

   with open(output_file, 'wb') as f:

        pdf_writer.write(f)

def main():

   parser = argparse.ArgumentParser()

   parser.add_argument('--input', type=file_path, default = None,

                        help='什么是输入PDF文件的路径?')

   parser.add_argument('--output', type=file_path, default = None,

                       help='什么是输出PDF文件的路径?')

   parser.add_argument('--pages', type=pages, default = None,

                       help='你想要提取哪些页?')

   args = parser.parse_args()

   split_merge_pdf(args.input, args.output, args.pages)

   print('PDF保存完成')

def file_path(path):

   return rf'{path}'

def pages(pages):

   return [int(i) for i in pages.split(',')]

if __name__ == '__main__':

   main()

在末尾添加了一个if __name__=='__main__'代码块。__name__Python中的一个特殊变量。当源文件作为主程序执行时(即从IDLE或命令行运行脚本),__name__将被设置为字符串”__main__”。从技术上讲,我们不需要这个if块,只需调用main(),代码仍然可以工作,但将其包含在代码中是一种很好的做法。

使用命令行界面运行Python脚本

实际测试一下这个程序。可以使用任何PDF文件进行测试,这里测试文件名是“data.pdf”。键入pdf_cli_eg.py --input=data.pdf --output=3_pages.pdf--pages=1,2,3。应该会看到与下面类似的输出,并且在程序运行后,在同一文件夹中应该会有一个名为“3_pages.PDF”的PDF文件。

Image

3

argparse的优点之一是它自动生成帮助消息。在命令行中,键入pdf_cli_eg.py -h。这将显示帮助消息,包括如何使用程序的CLI以及参数说明。

Image

4

注:本文学习整理自pythoninoffice.com

欢迎在下面留言,完善本文内容,让更多的人学到更完美的知识。

欢迎到知识星球:完美Excel社群,进行技术交流和提问,获取更多电子资料,并通过社群加入专门的微信讨论群,更方便交流。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多