如果您计划开展数据科学或机器学习项目,从Jupyter Notebook 开始开发并不罕见。它为您的计算工具提供交互性,让您可以快速运行模块等等。选择 Jupyter Notebook 作为主要工具有很多理由,特别是在进行数据科学或机器学习项目时。不过,本教程并不打算讨论这一部分。
设想您需要将一个 Python 脚本作为批处理作业来运行,以在数据科学项目中进行数据摄取;或者您需要运行一个 Python 脚本,将机器学习模型部署到远程服务器。在这些情况下,仅仅执行 python your_script.py 可能不够。您可能需要在 python your_script.py 之后再传入更多选项 或参数 。您或许已经熟悉在 Linux 终端运行命令(如 ps、ls 等)时使用附加参数的用法。
在本教程中,您将学习如何解析与 Python 脚本一起从命令行传入的其他参数和选项。以下是本教程的内容摘要:
参数解析的基本介绍
Python 中的参数解析
使用 sys.argv
使用 getopt
使用 argparse
注意 :本教程假设您已具备 Python 的基础知识。
什么是参数解析?
如果您是 Linux 用户,您很可能已经了解了。我敢打赌。为了获取某个目录下文件和文件夹的摘要,通常会使用 ls 命令。运行 ls 命令的典型输出如下所示——
不过,您可以为 ls 命令提供许多选项 ,例如 -l。我们来看看它的输出——
通过传入 -l 这个选项 ,您获得了更多信息。现在,在这个语境中,选项 和参数 之间有细微差别。要从当前工作目录中删除某个文件或文件夹,通常使用 rm 命令。假设您有一个名为 demo.txt 的文本文件,并运行 rm demo.txt 以删除该文件。在这种情况下,demo.txt 是您传给 rm 命令的参数 。如果您不给 rm 命令传入任何参数 ,您会得到如下错误——
那么,选项 和参数 的区别是什么?现在已经很明显了。选项是可选 的,而参数往往是必需 的。ls 命令不需要传入任何内容也能产生输出。
当您输入 ls -l 或 rm demo.txt 时,操作系统会在底层以特定方式对其进行解析。该机制通常由操作系统的开发者指定,称为解析 。
如果您有兴趣了解更多 Linux 命令以及它们支持的不同选项和参数,强烈推荐阅读《Unix Concepts and Applications 》一书。
以上是参数解析的基本介绍。几乎所有编程语言都支持参数解析,Python 也不例外。在 Python 中,常见的参数解析方式有三种——
接下来我们将逐一介绍上述选项,并了解如何用它们来解析参数(和选项)。让我们按时间顺序来。
使用 sys.argv 进行参数解析
我们从简单开始。在第一个示例中,您将创建一个名为 demo1.py 的 Python 文件。程序在执行时会接受从命令行(或终端)传入的任意数量的参数。程序将打印传入的参数以及参数总数。
例如,如果您执行 python demo1.py abc 123,程序将输出——
Number of arguments : 3
Argument ( s) passed: [ 'demo1.py' , 'abc' , '123' ]
技术支持
请注意,第一个参数始终是Python 文件的名称 。当然,代码可以修改为不包含它。
下面来看代码——
import sys
print ( 'Number of arguments: {}' . format ( len ( sys. argv) ) )
print ( 'Argument(s) passed: {}' . format ( str ( sys. argv) ) )
技术支持
您首先导入了 Python 模块 sys,它随标准的 Python 安装提供。然后使用了 argv 子模块,它会返回传给 Python 脚本的参数列表,其中 argv[0] 包含 Python 脚本的名称。如果您像下面这样在代码单元中运行 sys.argv,您会得到一组使 IPython 内核正常运行的配置文件列表。最好不要去动它们。
sys. argv
技术支持
[ '/home/nbuser/anaconda3_501/lib/python3.6/site-packages/ipykernel/__main__.py' ,
'-f' ,
'/home/nbuser/.local/share/jupyter/runtime/kernel-dabba4f7-e3e0-4c39-99d2-261ba835c53f.json' ]
技术支持
现在我们来看看如何使用 getopt 模块来解析参数(和选项)。
使用 getopt 进行参数解析
与 sys.argv 相比,getopt 模块提供了更强的灵活性。我们先设计一个示例场景,并据此编写代码。
假设您发布了一个尚未编写文档的 Python 脚本,但希望在用户以错误方式执行脚本时,仍能给出有意义的反馈。您的 Python 脚本做的只是将两个数字相加并输出结果。唯一的约束是,用户需要以命令行参数的形式与 Python 脚本一起传入输入。
更实际一点地说,脚本理想的执行方式是——
python add_numbers.py -a 3 -b 8
输出应为 11。这里,-a 和 -b 是选项,3 和 8 是传给脚本的参数。选项不仅提升可读性,还能帮助决定运算流程(想象一下如果您不是做加法而是做除法)。我们先来看代码。
import getopt
import sys
argv = sys. argv[ 1 : ]
sum = 0
try :
opts, args = getopt. getopt( argv, 'a:b:' , [ 'foperand' , 'soperand' ] )
if len ( opts) == 0 and len ( opts) > 2 :
print ( 'usage: add.py -a <first_operand> -b <second_operand>' )
else :
for opt, arg in opts:
sum += int ( arg)
print ( 'Sum is {}' . format ( sum ) )
except getopt. GetoptError:
print ( 'usage: add.py -a <first_operand> -b <second_operand>' )
sys. exit( 2 )
技术支持
思路是先用 sys.argv 获取所有参数,然后按需处理。现在来看最重要的一行代码——opts, args = getopt.getopt(argv, 'a:b:', ['foperand', 'soperand'])
getopt() 方法的签名如下:
getopt.getopt(args, shortopts, longopts=[])
args 是从命令行获取的参数列表。
shortopts 用于指定选项字母。如果您提供 a:,就表示脚本应接收选项 a,后跟一个值作为其参数。从技术上讲,您可以在此处使用任意数量的选项。在命令行传入这些选项时,必须以 '-' 作为前缀。
longopts 用于指定 shortopts 的扩展版本。它们必须以 '--' 作为前缀。
您将 shortopts 定义为 a:b:,这意味着 Python 脚本将接收两个字母选项——“a” 和 “b”。通过指定 “:”,您明确告知这些选项后面会跟随参数。
您将 longopts 定义为 ['foperand', 'soperand'],这表示代码可以接受 f_operand 和 s_operand 来替代 a 和 b 作为选项。但这些应始终以 -- 作为前缀。
getopt 模块还为您提供了一个方便的异常类 GetoptError,可用于定义有用的信息,从而指导用户如何使用您的 Python 脚本。这也是您将脚本的功能部分放入 try 块,并相应定义 except 块的原因。
以下是运行该 Python 脚本的方式:
注意 :上述脚本未 定义对 longopts 的处理。这一点可以留作练习。
现在来看如何使用 argparse 进行参数解析。
使用 argparse 进行参数解析
从上面的两种方式可以看出,它们并不是很易读 。当您看到 argparse 的实际用法时,也会同意前两种方式在灵活性方面有所欠缺。为理解 argparse 的用法,我们从一个代码片段开始,它实现了上一节所看到的场景。
import argparse
ap = argparse. ArgumentParser( )
ap. add_argument( "-a" , "--foperand" , required= True ,
help = "first operand" )
ap. add_argument( "-b" , "--soperand" , required= True ,
help = "second operand" )
args = vars ( ap. parse_args( ) )
print ( "Sum is {}" . format ( int ( args[ 'foperand' ] ) + int ( args[ 'soperand' ] ) ) )
技术支持
首先,和上面讨论的另外两个模块一样,argparse 也随 Python 的标准安装提供。您先实例化一个 argparse 对象。之后的事情写起来就简单多了。以如下代码为例——
ap.add_argument("-a", "--foperand", required=True,
help="first operand")
这里您添加了在运行 Python 脚本时期望提供的参数。您同时提供了该参数的字母版本和扩展版本。通过指定 required=True,您明确要求用户必须提供该参数。最后,您附加了一段有意义的参数说明,如果用户没有以正确方式执行脚本,这段说明将显示给用户。
第二个参数的定义部分也是相同的。您可以通过指定相应的键来访问给定的参数。
上述代码片段清楚地展示了使用 argparse 定义命令行参数解析任务是多么简洁灵活。以下是您可以如何尝试运行上述 Python 脚本:
注意使用 argparse 后流程变得多么简单。
下一步是什么?
感谢您读到本教程的最后。现在,您已经掌握了 Python 自带的、能够解析与脚本一同从命令行传入参数的模块。作为练习,您可以据此自定义自己的机器学习和数据科学项目,以便进行参数解析并将其变成实用的脚本工具。不仅是机器学习或数据科学,只要您觉得合适的地方都可以。这就是今天教程的全部内容。如果您希望提升 Python 技能,可以考虑学习 DataCamp 的 Python Data Science Toolbox(第 1 部分) 课程。
如果您计划开展数据科学或机器学习项目,从Jupyter Notebook 开始开发并不罕见。它为您的计算工具提供交互性,让您可以快速运行模块等等。选择 Jupyter Notebook 作为主要工具有很多理由,特别是在进行数据科学或机器学习项目时。不过,本教程并不打算讨论这一部分。
设想您需要将一个 Python 脚本作为批处理作业来运行,以在数据科学项目中进行数据摄取;或者您需要运行一个 Python 脚本,将机器学习模型部署到远程服务器。在这些情况下,仅仅执行
python your_script.py可能不够。您可能需要在python your_script.py之后再传入更多选项或参数。您或许已经熟悉在 Linux 终端运行命令(如ps、ls等)时使用附加参数的用法。在本教程中,您将学习如何解析与 Python 脚本一起从命令行传入的其他参数和选项。以下是本教程的内容摘要:
sys.argvgetoptargparse注意:本教程假设您已具备 Python 的基础知识。
什么是参数解析?
如果您是 Linux 用户,您很可能已经了解了。我敢打赌。为了获取某个目录下文件和文件夹的摘要,通常会使用
ls命令。运行ls命令的典型输出如下所示——不过,您可以为
ls命令提供许多选项,例如-l。我们来看看它的输出——通过传入
-l这个选项,您获得了更多信息。现在,在这个语境中,选项和参数之间有细微差别。要从当前工作目录中删除某个文件或文件夹,通常使用rm命令。假设您有一个名为demo.txt的文本文件,并运行rm demo.txt以删除该文件。在这种情况下,demo.txt是您传给rm命令的参数。如果您不给rm命令传入任何参数,您会得到如下错误——那么,选项和参数的区别是什么?现在已经很明显了。选项是可选的,而参数往往是必需的。
ls命令不需要传入任何内容也能产生输出。当您输入
ls -l或rm demo.txt时,操作系统会在底层以特定方式对其进行解析。该机制通常由操作系统的开发者指定,称为解析。如果您有兴趣了解更多 Linux 命令以及它们支持的不同选项和参数,强烈推荐阅读《Unix Concepts and Applications》一书。
以上是参数解析的基本介绍。几乎所有编程语言都支持参数解析,Python 也不例外。在 Python 中,常见的参数解析方式有三种——
接下来我们将逐一介绍上述选项,并了解如何用它们来解析参数(和选项)。让我们按时间顺序来。
使用 sys.argv 进行参数解析
我们从简单开始。在第一个示例中,您将创建一个名为
demo1.py的 Python 文件。程序在执行时会接受从命令行(或终端)传入的任意数量的参数。程序将打印传入的参数以及参数总数。例如,如果您执行
python demo1.py abc 123,程序将输出——请注意,第一个参数始终是Python 文件的名称。当然,代码可以修改为不包含它。
下面来看代码——
您首先导入了 Python 模块
sys,它随标准的 Python 安装提供。然后使用了argv子模块,它会返回传给 Python 脚本的参数列表,其中argv[0]包含 Python 脚本的名称。如果您像下面这样在代码单元中运行sys.argv,您会得到一组使 IPython 内核正常运行的配置文件列表。最好不要去动它们。现在我们来看看如何使用
getopt模块来解析参数(和选项)。使用 getopt 进行参数解析
与
sys.argv相比,getopt模块提供了更强的灵活性。我们先设计一个示例场景,并据此编写代码。假设您发布了一个尚未编写文档的 Python 脚本,但希望在用户以错误方式执行脚本时,仍能给出有意义的反馈。您的 Python 脚本做的只是将两个数字相加并输出结果。唯一的约束是,用户需要以命令行参数的形式与 Python 脚本一起传入输入。
更实际一点地说,脚本理想的执行方式是——
python add_numbers.py -a 3 -b 8输出应为 11。这里,
-a和-b是选项,3 和 8 是传给脚本的参数。选项不仅提升可读性,还能帮助决定运算流程(想象一下如果您不是做加法而是做除法)。我们先来看代码。思路是先用
sys.argv获取所有参数,然后按需处理。现在来看最重要的一行代码——opts, args = getopt.getopt(argv, 'a:b:', ['foperand', 'soperand'])getopt()方法的签名如下:getopt.getopt(args, shortopts, longopts=[])args是从命令行获取的参数列表。shortopts用于指定选项字母。如果您提供a:,就表示脚本应接收选项a,后跟一个值作为其参数。从技术上讲,您可以在此处使用任意数量的选项。在命令行传入这些选项时,必须以 '-' 作为前缀。longopts用于指定shortopts的扩展版本。它们必须以 '--' 作为前缀。您将
shortopts定义为a:b:,这意味着 Python 脚本将接收两个字母选项——“a” 和 “b”。通过指定 “:”,您明确告知这些选项后面会跟随参数。您将
longopts定义为['foperand', 'soperand'],这表示代码可以接受f_operand和s_operand来替代a和b作为选项。但这些应始终以--作为前缀。getopt模块还为您提供了一个方便的异常类GetoptError,可用于定义有用的信息,从而指导用户如何使用您的 Python 脚本。这也是您将脚本的功能部分放入try块,并相应定义except块的原因。以下是运行该 Python 脚本的方式:
注意:上述脚本未定义对
longopts的处理。这一点可以留作练习。现在来看如何使用
argparse进行参数解析。使用 argparse 进行参数解析
从上面的两种方式可以看出,它们并不是很易读。当您看到
argparse的实际用法时,也会同意前两种方式在灵活性方面有所欠缺。为理解argparse的用法,我们从一个代码片段开始,它实现了上一节所看到的场景。首先,和上面讨论的另外两个模块一样,
argparse也随 Python 的标准安装提供。您先实例化一个argparse对象。之后的事情写起来就简单多了。以如下代码为例——ap.add_argument("-a", "--foperand", required=True, help="first operand")这里您添加了在运行 Python 脚本时期望提供的参数。您同时提供了该参数的字母版本和扩展版本。通过指定
required=True,您明确要求用户必须提供该参数。最后,您附加了一段有意义的参数说明,如果用户没有以正确方式执行脚本,这段说明将显示给用户。第二个参数的定义部分也是相同的。您可以通过指定相应的键来访问给定的参数。
上述代码片段清楚地展示了使用
argparse定义命令行参数解析任务是多么简洁灵活。以下是您可以如何尝试运行上述 Python 脚本:注意使用
argparse后流程变得多么简单。下一步是什么?
感谢您读到本教程的最后。现在,您已经掌握了 Python 自带的、能够解析与脚本一同从命令行传入参数的模块。作为练习,您可以据此自定义自己的机器学习和数据科学项目,以便进行参数解析并将其变成实用的脚本工具。不仅是机器学习或数据科学,只要您觉得合适的地方都可以。这就是今天教程的全部内容。如果您希望提升 Python 技能,可以考虑学习 DataCamp 的 Python Data Science Toolbox(第 1 部分) 课程。